git/Documentation/gitmergeconflicts.adoc

341 lines
10 KiB
Plaintext

gitmergeconflicts(7)
====================
NAME
----
gitmergeconflicts - Guide to handling merge conflicts
DESCRIPTION
-----------
Merge conflicts can happen during a `git merge`, `git rebase`, `git
cherry-pick`, `git pull`, `git revert`, or any other command that does
a merge. All of those commands use the same merge algorithm, and the
process for resolving a merge conflict is always very similar.
There are 3 ways to handle a merge conflict:
* Resolve the conflict. (see <<resolve,HOW TO RESOLVE A MERGE CONFLICT>>
below for details)
* Stop the operation and return your branch to its original state
with the appropriate `--abort` command, for example `git merge --abort`
or `git rebase --abort`. See <<git_status,EXAMPLE: GIT STATUS OUTPUT>> below
for how to find the command to run.
* Or (if you're in a multi-step rebase or cherry-pick) skip the problematic
commit with the appropriate `--skip` command
WHAT IS A MERGE CONFLICT?
-------------------------
When Git merges two commits together, it looks at the changes that
each side has made and combines those changes. For example, if one side
edited lines 1-5 of `hello.py` and the other side edited lines 20-25 of
the same file, then it can easily combine them since there's no overlap.
But if both sides edited overlapping lines of the same file (for example
one side edited lines 1-5 and the other edited lines 3-6), Git will
not try to guess how to combine those changes. This is called a "merge
conflict".
When this happens, Git shows you both sides' edits and asks you to pick
how to resolve them. It:
* Stages all of the files which were successfully merged
* For the files with conflicts, it marks them as conflicted, puts both
sides' edits in the file, and leaves <<markers, merge conflict markers>>
that you need to resolve.
[NOTE]
================================
Even if Git successfully merges both sides with no conflicts, it's
possible to end up with code that doesn't work. For example, this can
happen if one side renames a function, and the other side adds a call to
the old function. This is called a "semantic merge conflict".
================================
[[markers]]
MERGE CONFLICT MARKERS
----------------------
When there's a merge conflict, Git will update the conflicted file
to include merge conflict markers `<<<<<<<`, `=======`, and `>>>>>>>`.
For example, here's a merge conflict where both sides edited a list of
fruits in different ways, and ended up in different states. One side
has "banana" but not "cherry", and the other side has "cherry", but
not "banana".
----
FRUITS = [
"apple",
<<<<<<< HEAD
"cherry",
=======
"banana",
>>>>>>> add-fruit
"mango",
"orange",
]
----
The lines from one side of the merge conflict are between `<<<<<<<` and
`=======`, and the lines from the other side are between `=======` and
`>>>>>>>`. See <<ours,"OURS" AND "THEIRS">> below for a full explanation
of which side is which.
[[resolve]]
HOW TO RESOLVE A MERGE CONFLICT
-------------------------------
The process for resolving a merge conflict is:
1. Run `git status` to get a list of files with merge conflicts
2. For each one, find the conflict markers
(the `<<<<<<<`, `=======`, `>>>>>>>`) and edit the code to
fix the conflict
3. Run `git add FILENAME` for each file to mark the conflict as resolved
4. Run the appropriate `--continue` command to continue the operation
that was interrupted by the conflict, for example `git merge --continue`
or `git rebase --continue`. See <<git_status,EXAMPLE: GIT STATUS OUTPUT>>
below for how to find the command to run.
+
Note: During a `git merge`, `git commit` and `git merge --continue` do
the same thing.
[[example]]
EXAMPLE OF RESOLVING A MERGE CONFLICT
-------------------------------------
If you see this in your code during a merge conflict:
----
FRUITS = [
"apple",
<<<<<<< HEAD
"cherry",
=======
"banana",
>>>>>>> add-fruit
"mango",
"orange",
]
----
Then you might edit that part of the code like this, to take
all the fruits from both sides of the conflict:
----
FRUITS = [
"apple",
"banana",
"cherry",
"mango",
"orange",
]
----
[[tools]]
TOOLS FOR HANDLING MERGE CONFLICTS
----------------------------------
Here are some ways to get extra context while handling a merge conflict:
* There are many graphical "merge tools" for Git, which will normally
show you the different versions of the code side by side.
If you have a mergetool configured, `git mergetool` will launch it.
See also `merge.tool` in linkgit:git-config[1] for a list of
the mergetools Git supports.
* You can set the configuration variable `merge.conflictstyle=diff3`.
See <<diff3,DIFF3>> below for more.
* `git log --merge -p <filename>` will list all commits which
caused the merge conflict for `<filename>`, and the diff
of how they changed the file.
* Look at the original files. `git show :1:filename` shows the
common ancestor, `git show :2:filename` shows the "ours"
version, and `git show :3:filename` shows the "theirs"
version. See <<ours,"OURS" AND "THEIRS">> below for more on
"ours" and "theirs".
Here are some ways to track your progress while handling a conflict:
* Use `git status` to get a list of files with conflicts
* Use `git diff --check` to make sure you haven't left any merge
conflict markers in a file by accident. It will print "leftover
conflict marker" if it finds any.
* Use `git diff AUTO_MERGE` to show what changes you've made so far to
resolve the conflicts.
See <<automerge,EXAMPLE OF USING `AUTO_MERGE`>> below for more.
[[git_status]]
EXAMPLE: GIT STATUS OUTPUT
--------------------------
When you're in a merge conflict, you can find out what commands to run
to handle the conflict by running `git status`.
For example, this `git status` output tells you that:
* `git rebase --abort` will safely bring your branch back to its
original state
* you should run `git rebase --continue` when you're done resolving all
the conflicts
* the conflicts in `fruits.py` haven't been marked as resolved
----
$ git status
You are currently rebasing branch 'main' on '58a9fcc'.
(fix conflicts and then run "git rebase --continue")
(use "git rebase --skip" to skip this patch)
(use "git rebase --abort" to check out the original branch)
Unmerged paths:
(use "git restore --staged <file>..." to unstage)
(use "git add <file>..." to mark resolution)
both modified: fruits.py
----
[[diff3]]
DIFF3
-----
By default, Git doesn't include the original code when formatting
a merge conflict. To include the original code, you can set the
configuration option `merge.conflictstyle` to `diff3`.
This extra context can make it easier to understand what's
happening in a merge conflict and avoid mismerges.
Here's an example of what a merge conflict would look like when using
`diff3`. There's an extra section (between `|||||||` and `=======`)
with the original code.
With this view, you can see that both sides fixed a spelling
mistake in "mango", and each removed one fruit from the list.
----
FRUITS = [
"apple",
<<<<<<< HEAD
"cherry",
"mango",
||||||| 1c22e48
"banana",
"cherry",
"mangoooo",
=======
"mango",
>>>>>>> add-fruit
"orange",
]
----
In the default format, you would see this conflict as shown before,
i.e., "one side has 'banana', the other side has 'cherry', everything
else is the same". But presented this way, we would realize that the
conflict resolution to keep "banana" and "cherry" we showed earlier
was incorrect. Rather, we want to drop "banana", and "cherry" and
keep the "mango" with corrected spellings. The `diff3` format is more
unambiguous by being more verbose.
[NOTE]
================================
`zdiff3` is an alternative to `diff3` that makes the merge conflict
shorter by making it more ambiguous.
================================
[[ours]]
"OURS" AND "THEIRS"
-------------------
Sometimes during a merge conflict, Git will use the terms "ours" and
"theirs" (or "us" and "them"). For example, `git status` might say that
a file was `deleted by us`.
"Ours" and "theirs" are both commits: "ours" is the current
`HEAD` commit, and "theirs" is the other side being merged.
The first part of a merge conflict (between `<<<<<<<` and `=======`) is
from the "ours" side, and the second part (between `=======` and
`>>>>>>>`) is from the "theirs" side.
----
FRUITS = [
"apple",
<<<<<<< HEAD
"cherry", <- ours
=======
"banana", <- theirs
>>>>>>> add-fruit
"mango",
"orange",
]
----
During a rebase, it can seem "upside down" because the "ours" commit is
from the branch you're rebasing on (for instance `main` in `git rebase
main`).
These terms in Git all mean the same thing when dealing with a merge
conflict:
* "common ancestor" and "base". The files from this commit are "in stage 1".
* "ours", "us", and `HEAD`. The files from this commit are "in stage 2".
* "theirs", "them". The files from this commit are "in stage 3".
If you're confused about what something like "deleted by us" means, it's
often easiest to use some of the tools from
<<tools,TOOLS FOR HANDLING MERGE CONFLICTS>> above to get more context.
Finding the commit that deleted the file and seeing why is usually more
helpful than trying to abstractly reason through what "us" means.
[[automerge]]
EXAMPLE OF USING `AUTO_MERGE`
-----------------------------
`git diff AUTO_MERGE` will show what changes you've made so far to
resolve conflicts. `AUTO_MERGE` is a reference that Git creates during a
merge. It contains the result of running the merge algorithm.
For example, if we resolved the conflict by adding both "banana" and
"cherry" in order, the diff would look like this:
----
FRUITS = [
"apple",
-<<<<<<< HEAD
- "cherry",
-=======
"banana",
->>>>>>> add-fruit
+ "cherry",
"mango",
"orange",
]
----
[NOTE]
`AUTO_MERGE` is only set if you're using the default Git merge algorithm.
SEE ALSO
--------
linkgit:git-revert[1]
linkgit:git-merge[1]
linkgit:git-rebase[1]
linkgit:git-cherry-pick[1]
linkgit:git-pull[1]
linkgit:git-diff[1]
GIT
---
Part of the linkgit:git[1] suite