15 minlesson

Understanding and Resolving Conflicts

Understanding and Resolving Conflicts

Conflicts happen when Git can't automatically merge changes. Learning to resolve them confidently is essential for team collaboration.

When Conflicts Occur

Conflicts happen when:

  • Two branches modify the same line differently
  • One branch deletes a file another branch modified
  • Both branches add files with the same name

Git handles many situations automatically, but when it can't determine the correct result, it asks you to decide.

Anatomy of a Conflict

When a conflict occurs, Git marks the file:

1<<<<<<< HEAD
2This is the content from your current branch
3=======
4This is the content from the branch being merged
5>>>>>>> feature-branch

Marker Meanings

MarkerMeaning
<<<<<<< HEADStart of your current branch's version
=======Separator between versions
>>>>>>> branchEnd of incoming branch's version

Three-Way Conflicts (During Rebase)

Sometimes you see three sections:

1<<<<<<< HEAD
2Your changes
3||||||| parent of abc123
4Original content (common ancestor)
5=======
6Their changes
7>>>>>>> abc123

The middle section shows the original, helping you understand what each side changed.

Resolution Strategies

Keep One Version

Sometimes you want to accept one side completely:

bash
1# Keep your version
2$ git checkout --ours file.txt
3
4# Keep their version
5$ git checkout --theirs file.txt

Manual Merge

Edit the file to combine both changes:

Before:

1<<<<<<< HEAD
2function greet() {
3 return "Hello!";
4}
5=======
6function greet(name) {
7 return `Hi ${name}!`;
8}
9>>>>>>> feature

After (manual resolution):

1function greet(name = "World") {
2 return `Hello, ${name}!`;
3}

Remove conflict markers and create the desired result.

Use a Merge Tool

Visual merge tools can help:

bash
1$ git mergetool

Configure your preferred tool:

bash
1$ git config --global merge.tool vscode
2$ git config --global mergetool.vscode.cmd 'code --wait $MERGED'

Popular merge tools:

  • VS Code (built-in)
  • Sublime Merge
  • Beyond Compare
  • Meld (Linux)
  • Kaleidoscope (macOS)

Conflict During Merge

bash
1$ git merge feature-branch
2Auto-merging app.js
3CONFLICT (content): Merge conflict in app.js
4Automatic merge failed; fix conflicts and then commit the result.

Resolution Steps

  1. Identify conflicts:

    bash
    1$ git status
    2Unmerged paths:
    3 both modified: app.js
  2. Edit conflicted files:

    bash
    1$ vim app.js
    2# Remove markers, create correct content
  3. Stage resolutions:

    bash
    1$ git add app.js
  4. Complete merge:

    bash
    1$ git commit
    2# Editor opens with merge commit message

Abort Merge

If you want to start over:

bash
1$ git merge --abort

Conflict During Rebase

bash
1$ git rebase main
2CONFLICT (content): Merge conflict in app.js
3error: could not apply abc123... Add feature

Resolution Steps

  1. Fix conflicts in files

  2. Stage resolutions:

    bash
    1$ git add app.js
  3. Continue rebase:

    bash
    1$ git rebase --continue
  4. Repeat for each conflicting commit

Skip or Abort

bash
1# Skip this commit (dangerous: loses changes)
2$ git rebase --skip
3
4# Cancel rebase entirely
5$ git rebase --abort

Rerere: Remember Resolutions

Enable rerere to remember how you resolved conflicts:

bash
1$ git config --global rerere.enabled true

Next time Git sees the same conflict, it auto-resolves:

bash
1$ git rebase main
2Resolved 'app.js' using previous resolution.

Review what rerere recorded:

bash
1$ git rerere diff

Conflict Prevention

Stay Updated

Regularly sync with main to minimize divergence:

bash
1$ git fetch origin
2$ git rebase origin/main

Small, Focused Changes

Large changes = more conflict potential. Small PRs merge easier.

Communicate with Team

If you know you'll modify heavily-used files, coordinate with teammates.

Common Conflict Scenarios

Binary Files

Git can't merge binary files. Choose one:

bash
1$ git checkout --ours image.png
2# or
3$ git checkout --theirs image.png
4$ git add image.png

Deleted vs Modified

One branch deleted a file, another modified it:

bash
1$ git status
2deleted by them: config.json
3
4# Keep the file
5$ git add config.json
6
7# Accept deletion
8$ git rm config.json

Renamed Files

If detection fails, Git sees it as delete + create:

bash
1# Check rename detection
2$ git diff --name-status main
3R100 old-name.js new-name.js

Key Takeaway

Conflicts are normal in collaborative development. Read the markers carefully, understand what each side changed, and create a resolution that preserves the intent of both changes. Enable rerere to avoid resolving the same conflicts repeatedly.