iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Resolving Conflicts

Merge conflicts happen when two branches change the same lines and Git can’t pick. The fix is mechanical: read the conflict markers, choose the right code, mark resolved, finish the merge. Knowing the tools (3-way diff, rerere, mergetool) turns scary moments into routine.

Markers, tools, prevention, abort

EXAMPLE
# 1) When a conflict occurs
git merge feature/login
# CONFLICT (content): Merge conflict in src/auth.ts
# Automatic merge failed; fix conflicts and then commit the result.

git status
# Unmerged paths:
#   both modified:   src/auth.ts

# 2) Conflict markers — what you'll see in the file
#
# <<<<<<< HEAD                          ← your branch's version
# const TOKEN_TTL = 3600;
# =======                                ← divider
# const TOKEN_TTL = 86400;                 ← incoming version
# >>>>>>> feature/login                  ← incoming branch
#
# You decide: pick yours, pick theirs, combine both, or write something new.

# 3) Resolve manually
# Edit the file, remove ALL markers, save.
git add src/auth.ts
git status
# All conflicts fixed but you are still merging.
git commit                                  # opens editor with a default merge message

# 4) Resolve with the CLI
git checkout --ours src/auth.ts             # keep your branch's whole file
git checkout --theirs src/auth.ts           # keep incoming whole file
# Then: git add src/auth.ts && git commit

# 5) Resolve with a merge tool (3-way diff)
git mergetool                                # uses configured tool (vimdiff, meld, kdiff3, VS Code, IntelliJ)
# Configure:
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'

# 6) Abort the merge — start over
git merge --abort
# Returns the working tree to the pre-merge state.

# 7) Look at the three versions
git checkout HEAD~ src/auth.ts                # COMMON ANCESTOR version (use --merge during rebase)
git show :1:src/auth.ts                       # common ancestor
git show :2:src/auth.ts                       # your version (ours)
git show :3:src/auth.ts                       # incoming (theirs)

git diff :2:src/auth.ts :3:src/auth.ts        # what changed between ours + theirs

# 8) Diff3 conflict style — shows the COMMON ANCESTOR too
git config --global merge.conflictstyle diff3
# Now markers include an extra section:
# <<<<<<< HEAD
# const TOKEN_TTL = 3600;
# ||||||| ancestor                       ← what both branches started from
# const TOKEN_TTL = 7200;
# =======
# const TOKEN_TTL = 86400;
# >>>>>>> feature/login
#
# Knowing the ancestor often makes the right choice obvious.

# 9) Conflicts during rebase
git rebase main
# Resolve, add the file, then:
git rebase --continue                         # apply the next commit
git rebase --skip                              # drop this commit and continue
git rebase --abort                             # give up, go back to where you started

# 10) Conflicts during cherry-pick
git cherry-pick abc1234
# Resolve, add file, then:
git cherry-pick --continue
git cherry-pick --skip
git cherry-pick --abort

# 11) rerere — REuse REcorded REsolution
git config --global rerere.enabled true
# Git records how you resolved a conflict; the next time the same conflict appears it auto-applies.
# Especially useful for long-running feature branches against fast-moving main.

# 12) Lockfile + generated file conflicts
# package-lock.json, pnpm-lock.yaml, yarn.lock, Cargo.lock, go.sum:
#   • Don't merge manually; regenerate after resolving package.json
#       git checkout --theirs package-lock.json
#       npm install
#       git add package-lock.json
#
# • Add to .gitattributes:
#       *.lock merge=lockfile
#   then in .git/config: [merge "lockfile"] driver = npm install   (tooling can be custom)

# 13) Binary file conflicts
git checkout --ours image.png
git checkout --theirs image.png
git add image.png
# Can't merge binary content; you must pick one or rebuild.

# 14) Preventing conflicts
# • Smaller PRs merged faster
# • Pull main into your branch daily (git pull --rebase or git merge main)
# • Split unrelated changes into separate commits
# • Refactor in a SEPARATE PR before adding features
# • Code owners + module ownership — fewer people touching the same file
# • Auto-formatters running on save — reduces noise conflicts on whitespace

# 15) Editor + IDE help
# VS Code:    'Merge Editor' shows current/incoming/result with click-to-accept
# IntelliJ:   'Resolve Conflicts' dialog; 3-way merge with semantic awareness
# GitHub:     Web editor for simple text conflicts

# 16) GitHub PR merge conflicts
# GitHub blocks merging when conflicts exist. Resolve locally:
git fetch origin
git checkout feature/login
git merge origin/main
# Resolve, push:
git push

# Or use the GitHub UI for trivial conflicts (only text-level edits).

# 17) Common bugs
# • Forgetting to remove ALL conflict markers → committing broken code
# • Choosing 'ours' when fixing a logic conflict → silently dropping the other team's work
# • Resolving lockfile conflicts manually → out-of-sync dependency tree
# • Conflict avoidance via long-lived branches → much bigger conflict later
# • Running 'git pull' on a branch with conflicts not resolved → confusing reset
# • CI green after 'theirs' resolution → tests passed but business logic dropped; READ DIFF before commit
# • Resolving rebase conflicts then forgetting --continue → state stuck in 'rebasing'
# • Reverting a merge without --mainline → fails on octopus merges; specify parent

Why it matters

Conflicts are mechanical: read the markers, pick the right code, git add, finish the merge. Enable diff3 conflict style so you see the common ancestor, rerere so Git remembers your resolutions, and reach for git mergetool when a 3-way diff is clearer. Don’t hand-merge lockfiles — regenerate after resolving the manifest.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
# Edit conflicting files, look for <<<<<<<.
git add resolved-file
git commit         # if merge
git rebase --continue    # if rebase
Try it Yourself »

Discussion

Loading…