Sooner or later, two people change the same lines of the same file on different branches, or you do it yourself on two of your own. When those branches meet, Git can't know which version is right, so it stops and asks you. That's a merge conflict.
Conflicts look alarming the first time: strange <<<<<<< lines appear in your files, and Git refuses to finish the merge. But they're a normal part of working with branches, and they're Git being careful rather than something going wrong. Nothing is lost; Git has kept both versions and is waiting for your decision.
Building on the merging lesson, you'll read conflict markers with extra context, keep one side in one command, handle conflicts during a rebase, back out safely and make conflicts rare.
Why conflicts happen
Git merges automatically whenever it can. Changes to different files, or to different parts of the same file, combine without any help. A conflict only happens when both branches changed the same lines (or lines right next to each other) in different ways, or when one branch edited a file that the other deleted.
When that happens, Git:
- Merges everything it can.
- Writes conflict markers into the files it couldn't merge.
- Pauses the merge and lists the files under "Unmerged paths" in
git status.
Nothing is committed until you resolve every file, git add it and finish the merge.
Reading conflict markers
<<<<<<< HEAD
<p>Open 9 to 5, Mon to Sat</p>
=======
<p>Open 8 to 6</p>
>>>>>>> new-hours- Between
<<<<<<< HEADand=======is your version: the branch you're on, also called "ours". - Between
=======and>>>>>>> new-hoursis the incoming version: the branch being merged in, "theirs".
Your job is to edit the file so it contains exactly what the final version should be, which is often a combination of both, and delete all three marker lines. Then git add the file to mark it resolved.
See the original too: zdiff3
By default you only see the two new versions, not what the line looked like before either change. Turn on the three-way style once:
git config --global merge.conflictStyle zdiff3Conflicts then include a middle section, after |||||||, showing the common ancestor. Seeing that the original said "Open 9 to 5" makes it obvious that one branch added the days and the other changed the hours, so the right answer keeps both changes.
Choosing a whole side, tools and aborting
git checkout --ours filekeeps your branch's version of the whole file;--theirskeeps the incoming one. Thengit addit.- Editors help a lot. VS Code shows Accept Current, Accept Incoming and Accept Both buttons above each conflict, and a three-way merge editor.
git diffduring a conflict shows only the unresolved parts.git merge --abort(orgit rebase --abort) cancels and puts everything back as it was before you started.
During a rebase, "ours" and "theirs" are swapped: ours is the branch you're rebasing onto, and theirs is your own commit being replayed. Read the labels in the markers rather than relying on memory.
Git Conflicts Syntax
Conflict commands
git status # lists unmerged files
git diff # shows unresolved parts
git checkout --ours file.txt # keep my version
git checkout --theirs file.txt # keep the incoming version
git add file.txt # mark as resolved
git commit # finish a merge
git rebase --continue # finish a rebase step
git merge --abort # cancel the merge
git config --global merge.conflictStyle zdiff3Git Conflicts Summary
- Conflicts happen when both branches change the same lines differently; Git pauses and marks them.
- HEAD (ours) is your current branch; the other label (theirs) is the incoming branch.
- Edit the file to the final version, remove all markers,
git addit, then commit or continue. - zdiff3 style shows the original lines too;
--oursor--theirskeeps one whole side. --abortcancels safely; in a rebase, ours and theirs are swapped.
Git Conflicts Examples
Each example shows the code, the output it produces and what each part does.
A conflict, step by step
git merge new-hours
git status
cat index.htmlAuto-merging index.html
CONFLICT (content): Merge conflict in index.html
Auto-merging style.css
CONFLICT (content): Merge conflict in style.css
Automatic merge failed; fix conflicts and then commit the result.
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
both modified: style.css
<h1>Welcome</h1>
<<<<<<< HEAD
<p>Open 9 to 5, Mon to Sat</p>
=======
<p>Open 8 to 6</p>
>>>>>>> new-hours
<footer>(c) 2024</footer>Line-by-line explanation
- Line 1main added the opening days; new-hours changed the hours, on the same line. The two files changed in both branches conflict.
- Line 2"both modified" means each branch changed these files in ways Git couldn't combine.
- Line 3The heading and footer merged fine; only the clashing line has markers.
Resolving: one by hand, one by choosing a side
git checkout --theirs style.css
git add style.css
# edit index.html to: <p>Open 8 to 6, Mon to Sat</p> and delete the markers
git add index.html
git status --short
git commit --no-edit
git log --oneline --graphUpdated 1 path from the index
M index.html
M style.css
* 2230dce Merge branch 'new-hours'
|\
| * 71ed3ae Update opening hours
* | 350e8c3 Add opening days
|/
* 1b206c5 Add home pageLine-by-line explanation
- Lines 1 to 2For the stylesheet, the new-hours colour is wanted as it is, so keep the incoming version.
- Lines 3 to 4For the page, combine both changes by hand: the new hours and the days.
- Line 5Both files are staged and resolved.
- Line 6--no-edit accepts Git's default merge message.
- Line 7The graph shows both branches joined by the merge commit.
Context with zdiff3, and a conflict during rebase
git config merge.conflictStyle zdiff3
git merge new-hours
cat index.html
git merge --abort
git switch new-hours
git rebase mainAuto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
<h1>Welcome</h1>
<<<<<<< HEAD
<p>Open 9 to 5, Mon to Sat</p>
||||||| 959899f
<p>Open 9 to 5</p>
=======
<p>Open 8 to 6</p>
>>>>>>> new-hours
Switched to branch 'new-hours'
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
error: could not apply ccbb356... Update opening hours
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".Line-by-line explanation
- Line 1zdiff3 adds the original text from the common ancestor, after |||||||.
- Line 3Now it's clear: one side added "Mon to Sat", the other changed "9 to 5" to "8 to 6".
- Line 4--abort cancels the merge completely, as if it never started.
- Line 6Rebasing replays new-hours' commit onto main and hits the same conflict. Resolve, git add, then git rebase --continue.
Common Git Conflicts Mistakes
Committing with markers still in the file
git add index.html # file still contains <<<<<<< and >>>>>>>
git commitgrep -n "<<<<<<<\|>>>>>>>" index.html # check nothing is left
git add index.html
git commitKeeping only one side without reading
git checkout --ours index.html # silently throws away the other branch's work# read both sides (and the original, with zdiff3), then combine themPanicking in the middle of a merge
rm -rf project && git clone ... # starting over loses unpushed workgit merge --abort # or git rebase --abortGit Conflicts in Real Projects
Conflicts in team work
On active teams, conflicts happen weekly in shared files like translation files and lock files. GitHub offers a web editor for small ones, and Git's rerere setting ("reuse recorded resolution") can remember how you resolved a conflict and repeat the fix next time.
Git Conflicts FAQ
How do I list the files that still have conflicts?
git status lists them under "Unmerged paths", usually marked "both modified". For just the names, run git diff --name-only --diff-filter=U. A file drops off the list once you git add it.
How do I resolve merge conflicts in VS Code?
Open the conflicted file and VS Code highlights each conflict, with clickable options above it such as Accept Current Change, Accept Incoming Change and Accept Both Changes. Pick one or edit the text by hand, save the file, then run git add on it as usual.
What do ours and theirs mean during a rebase?
They're the opposite of what you might expect. During a merge, "ours" is your current branch and "theirs" is the branch being merged in. During a rebase, Git is replaying your commits on top of the other branch, so "ours" is the branch you're rebasing onto and "theirs" is your own commit.
How do I start over on one file after resolving it badly?
Run git checkout --merge filename (or -m). It recreates the conflict markers in that file as they were when the merge stopped, so you can resolve it again. This only works before you commit the merge.
How do I resolve a conflict where one side deleted the file?
Git reports a "modify/delete" conflict, and git status shows the file as "deleted by them" or "deleted by us". To keep the file, run git add filename; to accept the deletion, run git rm filename. Then commit as for any other conflict.
Git Conflicts Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Complete the command that keeps your own branch's version of a conflicted file.
git checkout -- style.css
In conflict markers, what's between <<<<<<< HEAD and =======?
After editing a conflicted file, how do you mark it as resolved?
What does the zdiff3 conflict style add?
During git rebase main, what does --theirs refer to?
Git Conflicts Quiz
5 questions to check what you learned.
When does Git report a conflict?
- When both branches change the same lines differently
- Whenever two branches change any file
- When a branch has more than ten commits
- When you merge into main
How do you cancel a merge that has conflicts?
- git reset --merge-cancel
- git merge --abort
- Delete the .git folder
- git stop
What does "both modified" mean in git status?
- Two people are editing at once
- Both branches changed this file in ways Git couldn't combine
- The file was saved twice
- The file is staged
Which habit prevents most painful conflicts?
- Never using branches
- Always using --theirs
- Committing once a month
- Keeping branches short-lived and merging main into them often
What does Git's rerere feature do?
- Reverts merges
- Renames branches
- Remembers how you resolved a conflict and reuses that resolution when the same conflict appears again
- Re-runs tests