Git merge conflict markers (<<<<<<< HEAD, =======, >>>>>>>) explained, and how to resolve them

Git merges most changes by itself. When two branches changed the same lines differently, it stops, writes both versions into the file between marker lines, and asks you to choose. The markers are plain text that you delete once you have decided.

Reading the markers

<<<<<<< HEAD
const timeout = 30;
=======
const timeout = 60;
>>>>>>> feature/slow-network

The right answer might be one side, the other, or a mix of both (perhaps const timeout = 60; plus a comment from your side). Git can’t know; that’s why it asks.

Resolve, step by step

git status                     # lists "both modified:" files
# edit each file: keep what you want, delete the 3 marker lines
git diff                       # check what you're about to accept
git add src/config.js          # marks that file as resolved
git commit                     # finishes the merge (message is pre-filled)

Rebasing instead? After git add, run git rebase --continue; git may stop again for the next commit. Cherry-picking: git cherry-pick --continue.

Changed your mind? Back out

git merge --abort      # puts everything back as before the merge
git rebase --abort     # same for a rebase
git cherry-pick --abort

Ours and theirs flip during a rebase

OperationHEAD / “ours”“theirs”
git merge feature (on main)main, where you arefeature, coming in
git rebase main (on feature)main, plus your commits replayed so faryour feature commit being replayed
git pull (merge mode)your local branchthe remote branch
git stash popyour current filesthe stash (labelled Stashed changes)

A rebase replays your commits on top of the other branch, so “HEAD” is the other branch and your own work is “theirs”. That’s why git checkout --ours seems backwards during a rebase.

Take one whole side of a file

git checkout --ours   path/to/file    # keep my version (merge)
git checkout --theirs path/to/file    # take the incoming version (merge)
git add path/to/file

Handy for generated files. For lockfiles (package-lock.json, poetry.lock, yarn.lock) don’t hand-edit markers: take either side, then rerun npm install (or your tool’s equivalent) so it regenerates the file from the merged manifest.

See the original too: diff3 and zdiff3

git config --global merge.conflictStyle zdiff3   # git 2.35+; use diff3 on older git

Now conflicts include a third section, ||||||| base, showing what the lines looked like before either branch changed them. Knowing that the original was 30, and only one side changed it, often makes the choice obvious. To compare the two sides at leisure, paste them into the text diff tool.

Markers that slipped into a commit

Leftover markers break things in loud ways: SyntaxError: Unexpected token << in JavaScript, Unexpected token < in JSON, YAML that won’t parse, or a web page showing =======. Find them:

git diff --check                         # warns about leftover conflict markers in unstaged changes
git diff --cached --check                # same, for what you're about to commit
git grep -nE '^(<{7}|={7}|>{7})( |$)'   # search the whole repo

A broken JSON or YAML file is quickest to check by pasting it into the JSON formatter or YAML to JSON converter, which point at the line that fails. See also Unexpected token in JSON.

Fewer conflicts next time

Got here from a git pull that complained about divergent branches? Pick a pull strategy first.

Related

local changes would be overwritten by merge · All guides

Questions

What does <<<<<<< HEAD mean in git?

It marks the start of a merge conflict. The lines after it, up to =======, are the version from your current branch (HEAD). The lines after ======= up to >>>>>>> are the incoming version. You choose, delete the marker lines, then git add the file.

How do I finish resolving a merge conflict?

Edit every conflicted file so it has no marker lines left, run git add on each, then git commit to finish a merge, or git rebase --continue during a rebase.

How do I cancel a merge with conflicts?

Run git merge --abort (or git rebase --abort for a rebase). Git returns your branch and working files to how they were before you started.

Why are ours and theirs reversed during a rebase?

A rebase replays your commits on top of the other branch, so HEAD is the other branch and the commit being applied, your own, counts as theirs.

Published .

Try it

Related guides

Newest guides