Back to blog

Resolving conflicts

Conflicts mean Git found two versions of the same line and needs you to pick one. You'll fix most conflicts in under two minutes once you know the pattern.

April 7, 202612 min read
GitConflictsMergeRebaseVersion Control
Resolving conflicts
Resolving conflicts - How Git handles conflicting changes
Resolving conflicts - How Git handles conflicting changes

Conflicts mean Git found two versions of the same line and needs you to pick one.

Two people edited the same code. Or someone deleted a file another person changed. Git stops and waits for your decision.

You'll fix most conflicts in under two minutes once you know the pattern.


What a conflict looks like

Git marks the file with conflict boundaries:

<<<<<<< HEAD
const API_URL = "https://api.prod.com";
=======
const API_URL = "https://api.staging.com";
>>>>>>> feature-branch

Three sections:

  • <<<<<<< HEAD to ======= : your current branch
  • ======= to >>>>>>> : the incoming branch

Pick one version, combine both, or write something new. Delete the markers when done.


When conflicts happen

You'll see conflicts during:

  • git merge
  • git rebase
  • git pull
  • git cherry-pick
  • git stash pop

Same trigger each time: two branches changed the same lines in different ways.


Step by step resolution

1. See the conflicted files

git status

Conflicted files show as "both modified" or "both added".

Unmerged paths:
  both modified:   src/config.js
  both modified:   src/api/client.js

2. Open the file

Find the conflict markers. One file can have multiple conflicts.

function getUser(id) {
<<<<<<< HEAD
  return fetch(`/api/users/${id}`);
=======
  return axios.get(`/api/users/${id}`);
>>>>>>> feature-branch
}

3. Decide what to keep

Option A: Keep yours (HEAD)

function getUser(id) {
  return fetch(`/api/users/${id}`);
}

Option B: Keep theirs (incoming)

function getUser(id) {
  return axios.get(`/api/users/${id}`);
}

Option C: Combine both

function getUser(id) {
  // Using axios instead of fetch for better error handling
  return axios.get(`/api/users/${id}`);
}

Option D: Write something new

function getUser(id) {
  return httpClient.get(`/users/${id}`);
}

Delete the markers. The file should compile.

4. Mark as resolved

git add src/config.js

5. Continue

For merge:

git commit

For rebase:

git rebase --continue

For cherry-pick:

git cherry-pick --continue

Tools

VS Code

VS Code shows clickable buttons above each conflict:

  • "Accept Current Change"
  • "Accept Incoming Change"
  • "Accept Both Changes"
  • "Compare Changes"

TIP

"Compare Changes" opens a side-by-side diff. Use it for anything beyond a one-line conflict.

Git mergetool

git mergetool

Configure your editor:

  • VS Code: git config --global merge.tool vscode
  • Vim: git config --global merge.tool vimdiff
  • Meld: git config --global merge.tool meld

Lazygit

Lazygit handles conflicts in a visual interface. Arrow keys to navigate, shortcuts to pick versions. Article 8 covers this.


Conflict patterns

Different values

<<<<<<< HEAD
const timeout = 5000;
=======
const timeout = 10000;
>>>>>>> feature

Pick the right value.

Added vs modified

One branch added lines, another modified nearby code.

function init() {
<<<<<<< HEAD
  setupLogging();
  setupDatabase();
=======
  setupDatabase();
  setupCache();
>>>>>>> feature

You want all three:

function init() {
  setupLogging();
  setupDatabase();
  setupCache();
}

Delete vs modify

One branch deleted a file, another modified it.

git status
# deleted by us:   src/old-utils.js

Your choices:

  • Keep the deletion: git rm src/old-utils.js
  • Keep the file: git add src/old-utils.js

Rename conflicts

Both branches renamed the same file to different names.

git status
# both added:      src/utils/helpers.js
# both added:      src/lib/helpers.js

Pick one location, delete the other.


Reducing conflicts

Pull often

git pull origin main

Longer divergence means more conflicts.

Keep branches short-lived Merge in days, not weeks.

Talk to your team Two people editing the same file? One waits, or you split the work.

Use feature flags Ship behind flags instead of long-running branches.

NOTE

Some conflicts will happen in any codebase with multiple contributors. That's normal.


Aborting

Want to start over?

# Abort a merge
git merge --abort

# Abort a rebase
git rebase --abort

# Abort a cherry-pick
git cherry-pick --abort

You're back to before you started.

WARNING

After you commit a merge, abort won't work. Use git reset --hard HEAD~1 instead.


Conflicts during rebase

Rebase replays commits one by one. You might hit conflicts multiple times.

git rebase main
# CONFLICT in file.js

# Fix the conflict
git add file.js
git rebase --continue

# Another conflict in the next commit
# Fix again
git add file.js
git rebase --continue

# Done

Too painful? Switch to merge:

git rebase --abort
git merge main
🔍 Why rebase triggers more conflicts

Merge compares two endpoints and combines them once.

Rebase applies your commits one at a time onto the new base. Commit 1 might conflict. You fix it. Commit 2 might conflict with the now-modified file. You fix it again.

For branches with many commits touching the same files, you can end up resolving similar conflicts multiple times. Merge handles it in one pass.


After resolving

Before you commit:

# Check what you're about to commit
git diff --staged

# Run tests
npm test

# Build
npm run build

TIP

A bad resolution can break the build even when it looks correct. Test after every conflict.


Cheat sheet

CommandWhat it does
git statusSee conflicted files
git diffSee conflict details
git add <file>Mark as resolved
git merge --abortCancel merge
git rebase --abortCancel rebase
git rebase --continueContinue after fixing
git mergetoolOpen visual merge tool

The takeaway

Git asks for your input when it can't decide. Look at both versions, understand what each change intended, pick one. Done.

The more you resolve, the faster you get. After a few dozen, it's muscle memory.

Next article: exploring history with log, diff, and blame.


This is part 4 of my "Git & GitHub in 10 articles" series.

Questions? Reach out on LinkedIn or check out my blog.