Git Merge Conflicts
A merge conflict occurs when two branches have made different changes to the same part of the same file. Git cannot automatically decide which version is correct, so it pauses the merge and asks for a manual decision on how to resolve it.
Real-life analogy: Two people are editing the same sentence in a shared document at the same time. Person A changes it to "The sky is blue." Person B changes it to "The sky is clear." When combining the documents, it is impossible to automatically know which version to keep — a human decision is needed.
When Do Conflicts Happen?
Conflicts happen when:
- Two branches modify the same lines in the same file
- One branch deletes a file while another branch modifies it
- Two branches add different content at the same location
Simulating a Conflict — Step by Step
# Start: both branches begin from the same commit
git log --oneline
# a3f92b1 Add index.html
# ── Branch 1: main ──
# (Already on main)
# Edit line 2 of index.html to: <h1>Hello World</h1>
git add index.html
git commit -m "Update heading on main"
# ── Branch 2: feature ──
git switch -c feature-update
# Edit line 2 of index.html to: <h1>Welcome Everyone</h1>
git add index.html
git commit -m "Update heading on feature branch"
# ── Try to Merge ──
git switch main
git merge feature-update
# Output:
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
Understanding the Conflict Markers
When a conflict occurs, Git modifies the conflicting file and inserts special conflict markers. Opening the file shows something like this:
<html>
<body>
<<<<<<< HEAD
<h1>Hello World</h1>
=======
<h1>Welcome Everyone</h1>
>>>>>>> feature-update
</body>
</html>
| Marker | Meaning |
|---|---|
<<<<<<< HEAD | Start of changes from the current branch (the one being merged into) |
======= | Separator between the two versions |
>>>>>>> feature-update | End of changes from the incoming branch |
Resolving the Conflict
Resolving a conflict means manually editing the file to decide what the final content should be. Remove the conflict markers and keep the desired version.
Option 1 — Keep the Current Branch (HEAD) Version
<html>
<body>
<h1>Hello World</h1>
</body>
</html>
Option 2 — Keep the Incoming Branch Version
<html>
<body>
<h1>Welcome Everyone</h1>
</body>
</html>
Option 3 — Combine Both Versions
<html>
<body>
<h1>Hello World — Welcome Everyone</h1>
</body>
</html>
Completing the Merge After Resolution
After editing the file to remove the conflict markers and saving the desired version:
# Stage the resolved file
git add index.html
# Complete the merge with a commit
git commit -m "Resolve merge conflict in index.html"
Checking Conflict Status
git statusOutput during a conflict:
On branch main
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
Aborting the Merge
If the conflict is too complex or the merge needs to be reconsidered:
git merge --abortThis cancels the merge entirely and returns the repository to the state it was in before the merge attempt.
Using a Merge Tool
Instead of manually editing conflict markers, a visual merge tool can be used:
git mergetoolThis opens a configured visual diff tool (like VS Code, Vimdiff, or KDiff3) that shows the two conflicting versions side by side with an option to choose or combine them.
Configuring VS Code as the Merge Tool
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'
Multiple Conflicts in One Merge
A single merge can have conflicts across multiple files. Git marks all of them. Each conflicting file must be resolved and staged before completing the merge commit.
# Check which files have conflicts
git status
# Unmerged paths:
# both modified: index.html
# both modified: style.css
# Resolve index.html... save... then:
git add index.html
# Resolve style.css... save... then:
git add style.css
# Complete the merge
git commit
Tips for Avoiding Conflicts
- Pull and merge frequently — the longer branches diverge, the more conflicts accumulate
- Keep feature branches small and short-lived
- Communicate with teammates about which files are being edited
- Follow a consistent code formatting standard to avoid whitespace conflicts
Summary
A merge conflict happens when two branches change the same part of the same file. Git marks the conflict in the file with special markers (<<<, ===, >>>). Resolution means manually editing the file to remove the markers and keep the correct content. After saving, stage the file and commit to complete the merge. Conflicts are normal — they are resolved by deciding which version of the code should survive.
