Key concepts

Merge conflict

A merge conflict happens when Git is combining changes and cannot safely decide which version of a file should win.

Despite the name, merge conflicts can appear during several Git operations, not only when you run git merge. They can happen when you:

  • Merge one branch into another with git merge.
  • Reapply commits on top of another branch with git rebase.
  • Pull remote changes with git pull, because pulling usually performs a merge or rebase after fetching.
  • Apply one commit somewhere else with git cherry-pick.
  • Undo a commit with git revert, if the reverse change does not apply cleanly.
  • Reapply stashed changes with git stash pop or git stash apply.

Conflicts usually happen when two branches changed the same lines in a file, or when one branch changed a file that another branch deleted or renamed. Git stops the operation so you can make the final decision.

Related errors such as "your local changes would be overwritten" are not quite the same thing. In that case, Git usually stops before starting the operation, so you can save or discard your local changes first.

When a text file has a content conflict, Git writes conflict markers into the file:

<<<<<<< HEAD
the version from your current branch
=======
the version Git is trying to bring in
>>>>>>> feature-branch

The part above ======= is one side of the conflict. The part below it is the other side. Your job is to edit the file into the final version you actually want, then remove all conflict markers.

Ours and theirs

Git and code editors sometimes label the two sides of a conflict as ours and theirs. Some tools use labels such as current and incoming for the same idea. Be careful with these names: they describe the sides of the current Git operation, not necessarily "my work" and "someone else's work".

For a regular merge, the meaning is usually intuitive:

git switch main
git merge feature
  • Ours is main, the branch you were on before starting the merge.
  • Theirs is feature, the branch being merged in.

During a rebase, the labels can feel backwards:

git switch feature
git rebase main

Git temporarily puts your work on top of main. If a conflict happens while Git is replaying a feature commit:

  • Ours is the main side, because that is the current checked-out base during the rebase.
  • Theirs is the feature commit being replayed.

This means choosing ours during a rebase can discard the change from the branch you think of as "yours". Commands such as git restore --ours path/to/file and git restore --theirs path/to/file choose one whole side of a conflicted file, so use them only when you are sure which side Git means in the current operation.

How to resolve one

The usual flow is:

  1. Run git status to see which files are conflicted.
  2. Open each conflicted file and edit it into the correct final version.
  3. Remove the <<<<<<<, =======, and >>>>>>> marker lines.
  4. Stage the resolved files with git add.
  5. Continue the operation: commit the merge, run git merge --continue, or run git rebase --continue, depending on what Git tells you.

Git does not check whether your resolution is logically correct. Once you stage the file, Git treats that content as the answer. Read the result before continuing.

If the conflict happened unexpectedly and you are not ready to resolve it, you can often return to the previous state with git merge --abort or git rebase --abort.