Resolving Merge Conflicts
A merge conflict occurs when Git cannot automatically reconcile changes from two branches to the same region of a file — for example, both branches edited the same line differently since diverging from their common ancestor. Git is conservative here: rather than guessing which change is correct, it pauses the merge, marks the affected files as conflicted, and leaves it to the developer to decide the correct outcome. Understanding this workflow removes much of the anxiety conflicts otherwise cause, because the process is mechanical and fully recoverable at every step.
Cricket analogy: Two batsmen call for the same run with contradictory calls, so the umpire pauses play and refers to the third umpire rather than guessing, forcing the batsmen to sort out the correct outcome together.
Reading conflict markers
When a conflict occurs, Git writes both versions directly into the affected file, delimited by conflict markers: <<<<<<< HEAD begins the version from your current branch, ======= separates it from the incoming version, and >>>>>>> branch-name ends the incoming branch's version. The file otherwise looks normal outside these marked regions — only the genuinely conflicting hunks are wrapped this way. Your job is to edit the file to reflect the correct final content, removing the marker lines entirely once you've decided what to keep.
Cricket analogy: A scorecard shows both the on-field umpire's original decision and the third umpire's revised call bracketed together, and the official scorer edits it down to one final ruling, removing the bracketed markers.
The resolution workflow
After a conflicted merge, git status lists every file with unresolved conflicts under 'Unmerged paths'. For each one, open the file, resolve the conflicting sections by hand (or with a merge tool via git mergetool), and once satisfied, stage it with git add <file> — staging a previously-conflicted file is how you tell Git 'this conflict is resolved.' After every conflicted file has been staged, run git commit with no message argument; Git will open an editor pre-filled with a sensible default merge commit message that you can accept or edit.
Cricket analogy: The scorer's checklist lists every disputed delivery under 'pending review'; each is settled via the third umpire, ticked off, and only once every disputed ball is ticked does the match officially resume.
$ git merge feature/pricing-update
Auto-merging src/pricing/calculator.py
CONFLICT (content): Merge conflict in src/pricing/calculator.py
Automatic merge failed; fix conflicts and then commit the result.
$ cat src/pricing/calculator.py
def apply_discount(price, code):
<<<<<<< HEAD
if code == "SAVE10":
return price * 0.90
=======
if code in VALID_PROMO_CODES:
return price * DISCOUNT_TABLE[code]
>>>>>>> feature/pricing-update
# After manually merging the logic together:
$ git add src/pricing/calculator.py
$ git status
All conflicts fixed but you are still merging.
$ git commit
[main 8b1c2d3] Merge branch 'feature/pricing-update'
# To keep entirely one side's version of a conflicted file:
$ git checkout --ours src/pricing/calculator.py # keep current branch's version
$ git checkout --theirs src/pricing/calculator.py # keep incoming branch's version
$ git add src/pricing/calculator.pygit diff during an unresolved merge shows a special combined diff format highlighting exactly which lines came from which side, and git log --merge can list the commits on both branches that touched the conflicted file, which is often faster than guessing intent from the marker text alone.
git checkout --ours / --theirs blindly picks one side wholesale for a file — it does not intelligently combine both changes. Using it without reviewing the discarded side can silently drop a teammate's work.
- A merge conflict happens when both branches changed overlapping content in incompatible ways since diverging.
- Git marks conflicted regions with
<<<<<<<,=======, and>>>>>>>and leaves resolution to the developer. git statuslists all unresolved files under 'Unmerged paths' during a conflicted merge.- Staging a file with
git addafter editing it signals to Git that its conflict is resolved. git commit(with no message) completes a merge once every conflict is staged, using a default merge message.git merge --abortcleanly cancels an in-progress conflicted merge and restores the pre-merge state.
Practice what you learned
1. What do the conflict markers `<<<<<<<` and `>>>>>>>` represent in a conflicted file?
2. How do you tell Git that you have finished resolving a conflict in a specific file?
3. What does `git checkout --theirs <file>` do during a conflict?
4. How do you cleanly cancel an in-progress merge that has unresolved conflicts, restoring the pre-merge state?
5. Where can you see the list of files that still have unresolved conflicts during a merge?
Was this page helpful?
You May Also Like
Merging Branches
Understand how git merge combines diverged branch histories, the difference between fast-forward and three-way merges, and when each occurs.
Rebasing vs Merging
Compare git rebase and git merge as two different strategies for integrating branch changes, and learn when a linear history is worth the trade-offs of rewriting commits.
git revert vs git reset
Two different ways to undo changes in Git — revert creates a new commit that inverses a prior one, while reset moves the branch pointer and rewrites history — and when to use each safely.
Common Git Pitfalls
A field guide to the mistakes that trip up both new and experienced Git users, why each one happens, and how to avoid or recover from it.
Related Reading
Related Study Notes in Software Engineering
Browse all study notesMicroservices Study Notes
Software Architecture · 30 topics
Software EngineeringTesting & TDD Study Notes
Software Testing · 30 topics
Software EngineeringDesign Patterns Study Notes
Software Design · 30 topics
Software EngineeringSoftware Engineering Study Notes
Python · 40 topics
Software EngineeringSystem Design Study Notes
Architecture · 40 topics