阿里云主机折上折
  • 微信号
Current Site:Index > Resolve merge conflicts

Resolve merge conflicts

Author:Chuan Chen 阅读数:51875人阅读 分类: 开发工具

Causes of Merge Conflicts

Git merge conflicts typically occur when two branches make different modifications to the same part of the same file. When Git cannot automatically decide which changes to keep, a conflict arises. Common scenarios include:

  1. Two branches modify the same line in the same file
  2. One branch deletes a file while another modifies it
  3. Merging binary files (Git cannot automatically merge binary files)
// Modification in Branch A
function add(a, b) {
  return a + b;
}

// Modification in Branch B
function add(a, b) {
  console.log('Adding numbers');
  return a + b;
}

Identifying Merge Conflicts

When executing git merge or git pull, if a conflict occurs, Git will explicitly notify:

CONFLICT (content): Merge conflict in file.js
Automatic merge failed; fix conflicts and then commit the result.

Conflicted files are marked by Git with special conflict markers:

<<<<<<< HEAD
// Code from the current branch
=======
// Code from the branch being merged
>>>>>>> branch-name

Basic Steps to Resolve Merge Conflicts

  1. Use git status to check which files have conflicts
  2. Open the conflicted file and locate the conflict markers
  3. Decide which changes to keep or perform a manual merge
  4. Remove the conflict markers (<<<<<<<, =======, >>>>>>>)
  5. Use git add to mark the resolved file as resolved
  6. Use git commit to complete the merge

Detailed Methods for Manual Conflict Resolution

Resolving Text File Conflicts

For simple text conflicts, you can directly edit the file:

// Conflicted state
<<<<<<< HEAD
function greet() {
  return "Hello";
}
=======
function greet() {
  return "Hi there";
}
>>>>>>> feature-branch

// After resolution
function greet() {
  return "Hello there";
}

Using Graphical Tools

Git supports various graphical merge tools:

  • git mergetool command
  • VS Code's Git integration
  • Third-party tools like SourceTree
git config --global merge.tool vscode
git mergetool

Advanced Conflict Resolution Techniques

Accepting Specific Version Changes

You can fully accept changes from one side:

# Accept changes from the current branch (ours)
git checkout --ours file.js

# Accept changes from the branch being merged (theirs)
git checkout --theirs file.js

Using Merge Strategies

# Recursive strategy (default)
git merge -s recursive branch-name

# Ours strategy (prefer current branch)
git merge -s ours branch-name

# Theirs strategy (prefer merged branch)
git merge -s theirs branch-name

Handling Complex Conflict Scenarios

Multiple Conflicted Files

When multiple files have conflicts, you can process them in bulk:

# View all conflicted files
git diff --name-only --diff-filter=U

# Use sed to batch accept our changes
git diff --name-only --diff-filter=U | xargs sed -i '/^<<<<<<< /,/^>>>>>>> /d'

Binary File Conflicts

Binary files require manual decisions on which version to keep:

# Keep the current branch version
git checkout --ours image.png

# Or keep the merged branch version
git checkout --theirs image.png

Undoing Merge Operations

If the merge encounters issues, you can undo it:

# When the merge hasn't been committed yet
git merge --abort

# When the merge has been committed
git reset --hard ORIG_HEAD

Best Practices to Prevent Merge Conflicts

  1. Frequently merge the main branch into feature branches
  2. Keep commits small in scope
  3. Use git pull --rebase instead of a regular pull
  4. Maintain consistent code styles within the team
  5. Configure merge strategies using .gitattributes files
# Example .gitattributes
*.js merge=union
*.png binary

Automated Merge Tools

You can configure custom merge drivers:

# .git/config
[merge "filfre"]
	name = Feel-free merger
	driver = filfre %O %A %B %L %P
	recursive = binary

Handling Submodule Conflicts

Submodule conflicts require special handling:

# Update submodules to the specified commit
git submodule update --init --recursive

# Resolve conflicts within the submodule directory
cd submodule-dir
git checkout desired-commit
cd ..
git add submodule-dir

Ignoring Whitespace During Merges

Whitespace often causes unnecessary conflicts:

git merge -Xignore-all-space branch-name
git merge -Xignore-space-change branch-name

Using Three-Way Merge Base

Understanding the merge base helps resolve complex conflicts:

# View the merge base
git merge-base HEAD branch-name

# Compare changes
git diff $(git merge-base HEAD branch-name) branch-name

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.