The brief
Create a scenario where two branches conflict; practice the full resolution flow. Until you've done this 5+ times, conflicts feel scary. After: routine.
Step 1: Setup (10 min)
mkdir conflict-drill && cd conflict-drill
git init
echo "Hello, world" > greeting.txt
git add . && git commit -m "Initial: greeting"
Now create the conflict scenario:
# Make branch A
git switch -c branch-a
echo "Hi, world!" > greeting.txt # change "Hello" to "Hi"
git commit -am "branch-a: friendlier greeting"
# Make branch B (from main)
git switch main
git switch -c branch-b
echo "Hello, world!" > greeting.txt # add an exclamation mark
git commit -am "branch-b: add exclamation"
git log --all --oneline --graph
# Should show two branches diverging from main
Step 2: Provoke the conflict (10 min)
git switch main
git merge branch-a # fast-forward; main moves to branch-a's tip
git merge branch-b # CONFLICT
# Auto-merging greeting.txt
# CONFLICT (content): Merge conflict in greeting.txt
# Automatic merge failed; fix conflicts and then commit the result.
Check status:
git status
# Unmerged paths:
# both modified: greeting.txt
Step 3: Inspect and resolve (15 min)
cat greeting.txt
# <<<<<<< HEAD
# Hi, world!
# =======
# Hello, world!
# >>>>>>> branch-b
Edit greeting.txt. Decide:
- Keep HEAD ("Hi, world!") → delete bottom + markers.
- Keep branch-b ("Hello, world!") → delete top + markers.
- Combine ("Hi, world!!!") → custom edit.
Try each:
# Version 1: keep mine (HEAD)
echo "Hi, world!" > greeting.txt
git add greeting.txt
git status # should show clean staging
git commit # finalize
Then git reset --hard HEAD~1 to undo and try again.
Step 4: Three-way conflict (with diff3)
Enable diff3 to see the base:
git config --global merge.conflictstyle diff3
Reset and try again:
git reset --hard HEAD~1 # back to after first merge (main was at branch-a's tip)
git merge branch-b
cat greeting.txt
# <<<<<<< HEAD
# Hi, world!
# ||||||| base
# Hello, world
# =======
# Hello, world!
# >>>>>>> branch-b
Now you see what each side CHANGED from the base — better basis for resolution.
Step 5: Abort vs continue
Practice aborting mid-merge:
git merge --abort
# Restores pre-merge state
git status # clean
Step 6: Multi-file conflict (15 min)
Make it more realistic — two files conflicting:
git switch main
git reset --hard HEAD~1 # the commit before the multi-file merge
git switch branch-a
echo "Welcome!" > greeting.txt
echo "v2" > version.txt
git commit -am "branch-a: v2"
git switch branch-b
echo "Howdy!" > greeting.txt
echo "v3" > version.txt
git commit -am "branch-b: v3"
git switch main
git merge branch-a
git merge branch-b
# Two conflicts!
git status
# Unmerged paths:
# both modified: greeting.txt
# both modified: version.txt
Resolve both:
vim greeting.txt # edit
git add greeting.txt
vim version.txt # edit
git add version.txt
git commit # finalize
Step 7: Rebase with conflicts
Rebase brings conflicts one commit at a time:
git reset --hard HEAD~1 # the commit before the rebase
git switch branch-b
git rebase branch-a
# Conflict on each commit; resolve and continue
git add file.txt
git rebase --continue
If stuck: git rebase --abort.
Deliverables
Submission contract: upload NOTES.md (conflict-marker anatomy, the edit→add→commit flow, how --abort saves you, merge-vs-rebase conflict difference).
100-pt rubric: provoke + resolve a conflict end-to-end (25) / diff3 base shown and used (20) / --abort demonstrated (15) / multi-file conflict resolved (25) / rebase conflict resolved (15).
upload NOTES.md (conflict-marker anatomy, the edit→add→commit flow, how --abort saves you, merge-vs-rebase conflict difference).
provoke + resolve a conflict end-to-end (25) / diff3 base shown and used (20) / --abort demonstrated (15) / multi-file conflict resolved (25) / rebase conflict resolved (15).
upload NOTES.md (conflict-marker anatomy, the edit→add→commit flow, how --abort saves you, merge-vs-rebase conflict difference).
provoke + resolve a conflict end-to-end (25) / diff3 base shown and used (20) / --abort demonstrated (15) / multi-file conflict resolved (25) / rebase conflict resolved (15).
- Show you can do the full cycle: provoke conflict → resolve → commit → verify.
- A
NOTES.mddescribing:- The conflict marker structure (HEAD/base/incoming).
- The 3-step resolution flow (edit, add, commit).
- How
--abortsaves you. - Difference between merge conflict and rebase conflict.
What you'll learn
- The mechanics of merge conflicts.
- Reading conflict markers.
- The resolve-add-commit flow.
diff3style for ancestor context.--abortas your safety net.- Multi-file conflict handling.
Stretch
- Use a merge tool (
git mergetoolor VS Code). - Practice with binary files (different image versions).
- Try
git rerere(reuse recorded resolution) for repeat conflicts.