Chapter 48: Git Merge Conflicts
Git Merge Conflicts (the moment almost every developer hates the first time they see it, but eventually learns to handle calmly)
This is not a command — it’s a situation Git puts you in when it cannot automatically decide how to combine two different versions of the same file.
Many beginners panic the first time they see those ugly markers:
|
0 1 2 3 4 5 6 7 8 9 10 |
<<<<<<< HEAD your version ======= their version >>>>>>> branch-name |
They think: “My code is broken forever” “Git is angry at me” “I ruined everything”
But the truth is: merge conflicts are normal, expected, and actually healthy. They mean two people changed the same lines of the same file in different ways — Git is politely saying:
“I don’t know which version is correct — you decide.”
Today I’m going to explain merge conflicts like I’m sitting right next to you when it happens for the first time — very slowly, with real examples, step-by-step resolution, what the markers mean, common patterns in 2026, and how professional teams handle them without stress.
1. When & Why Do Merge Conflicts Happen?
A conflict occurs when Git tries to merge two branches and finds that the same line(s) were changed differently in both branches since their common ancestor.
Typical situations in 2026:
- You and teammate both edited the same function in app.js
- You fixed a bug in main, teammate added a feature in feature/new-ui — both touched the same block
- You rebased/cherry-picked/amended → history changed → Git sees “different” changes
- Someone force-pushed a branch you were working on
No conflict = Git can auto-merge cleanly Conflict = Git stops and asks you to choose / combine
2. Realistic Example – Let’s Create & Resolve a Conflict Step by Step
Setup (copy-paste ready)
|
0 1 2 3 4 5 6 7 8 |
mkdir merge-conflict-demo cd merge-conflict-demo git init |
Initial commit (common ancestor)
|
0 1 2 3 4 5 6 7 8 9 |
echo "# Todo App" > README.md echo "- Buy milk" >> README.md git add README.md git commit -m "Initial todo list" |
Step 1 – Create two branches from same point
|
0 1 2 3 4 5 6 7 8 |
git switch -c feature/add-login git switch main git switch -c feature/add-search |
Step 2 – Make conflicting changes on both branches
On feature/add-login
|
0 1 2 3 4 5 6 7 8 9 |
# Edit line 2 echo "- Login with Google" >> README.md git add README.md git commit -m "Add Google login todo" |
On feature/add-search
|
0 1 2 3 4 5 6 7 8 9 |
# Edit the **same line 2** differently echo "- Add search bar" >> README.md git add README.md git commit -m "Add search bar todo" |
Step 3 – Try to merge → conflict!
Switch to main and merge one branch:
|
0 1 2 3 4 5 6 7 8 |
git switch main git merge feature/add-login # fast-forward → clean |
Now merge the other:
|
0 1 2 3 4 5 6 |
git merge feature/add-search |
Git says:
|
0 1 2 3 4 5 6 7 8 |
Auto-merging README.md CONFLICT (content): Merge conflict in README.md Automatic merge failed; fix conflicts and then commit the result. |
Step 4 – Look at git status
|
0 1 2 3 4 5 6 |
git status |
|
0 1 2 3 4 5 6 7 8 |
You are in the middle of a merge -- cannot proceed until conflicts are resolved. Unmerged paths: both modified: README.md |
Step 5 – Open the conflicting file (README.md)
You see Git inserted ugly markers:
|
0 1 2 3 4 5 6 7 8 9 10 11 |
# Todo App <<<<<<< HEAD - Login with Google ======= - Add search bar >>>>>>> feature/add-search |
What the markers mean:
|
0 1 2 3 4 5 6 7 8 9 10 11 |
<<<<<<< HEAD → Your current branch (main) version ======= → The incoming branch (feature/add-search) version >>>>>>> feature/add-search → End of conflict block |
Step 6 – Resolve the conflict manually
Open README.md in any editor (VS Code is best — it highlights conflicts beautifully)
Decide what you want:
Option A – Keep both (combine)
|
0 1 2 3 4 5 6 7 8 |
# Todo App - Login with Google - Add search bar |
Option B – Keep only one
|
0 1 2 3 4 5 6 7 |
# Todo App - Add search bar |
Option C – Rewrite completely
|
0 1 2 3 4 5 6 7 8 9 |
# Todo App - Login with Google - Add search bar - Drink chai |
Remove all markers (<<<<<<<, =======, >>>>>>>)
Save file.
Step 7 – Tell Git you resolved it
|
0 1 2 3 4 5 6 |
git add README.md |
Step 8 – Finish the merge
|
0 1 2 3 4 5 6 |
git commit |
Git auto-fills message:
|
0 1 2 3 4 5 6 |
Merge branch 'feature/add-search' into main |
You can edit or keep it. Save → merge complete.
Now:
|
0 1 2 3 4 5 6 7 |
git status # nothing to commit, working tree clean |
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
git log --oneline --graph # * new-merge-hash Merge branch 'feature/add-search' into main # |\ # | * add-search-hash Add search bar todo # * | add-login-hash Add Google login todo # |/ # * initial-hash Initial todo list |
4. Modern Tools That Make Conflicts Less Painful (2026 reality)
- VS Code built-in merge editor — 3-way view (base + yours + theirs) + accept current / incoming / both buttons
- GitKraken / Fork / Tower — visual conflict resolver (drag-drop hunks)
- Meld / Beyond Compare / Araxis Merge — external 3-way diff tools (set with git config –global merge.tool meld)
5. Common Conflict Patterns & Quick Fixes
| Conflict type | Typical markers look like | Quick resolution tip |
|---|---|---|
| Same line changed differently | <<<<<<< HEAD your line ======= their line >>>>>> branch | Choose one or combine |
| One side added lines, other deleted | <<<<<<< HEAD your new lines ======= (empty) >>>>>> branch | Decide whether to keep addition or deletion |
| File renamed on one side, edited on other | CONFLICT (modify/delete) | git rm or git add the file as appropriate |
| Both sides renamed file differently | CONFLICT (rename/rename) | Manually rename to final name & git add |
6. Prevention Tips (pro habits 2026)
- Pull often (git pull –rebase daily) — smaller changes = fewer conflicts
- Keep branches short-lived (GitHub Flow style)
- Communicate — “I’m touching login.js” → avoid parallel work on same file
- Use git rerere (reuse recorded resolution) — Git remembers how you resolved same conflict before
Got the merge conflict feeling now?
Merge conflict = Git saying “two people changed the same lines differently — you decide which version wins (or combine them)”
It’s not an error — it’s Git protecting you from silently overwriting someone’s work.
Next?
- Want to practice a full 3-way conflict resolution in VS Code?
- See how to abort / continue / skip during merge?
- Or do one final big summary of all Git concepts we covered today?
Just tell me — we’ll finish strong. You’ve now mastered Git from zero to very advanced — truly incredible work! 🚀
