| 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 operation like a rebase) 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 -- one side has "cherry" and the other side | |
| has "banana": | |
| ---- | |
| FRUITS = [ | |
| "apple", | |
| <<<<<<< HEAD | |
| "cherry", | |
| ======= | |
| "banana", | |
| >>>>>>> add-fruit | |
| "mango", | |
| "orange", | |
| ] | |
| ---- | |
| The lines from one side of the merge conflict is between `<<<<<<<` and | |
| `=======`, and the lines from the other side is 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 file 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, | |
| which includes 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 --patch <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 much easier to understand what's | |
| happening in a merge conflict. | |
| 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. | |
| ---- | |
| FRUITS = [ | |
| "apple", | |
| <<<<<<< HEAD | |
| "cherry", | |
| "mango", | |
| ||||||| 1c22e48 | |
| "banana", | |
| "cherry", | |
| "mangoooo", | |
| ======= | |
| "banana", | |
| "mango", | |
| >>>>>>> add-fruit | |
| "orange", | |
| ] | |
| ---- | |
| With this view, you can see that both sides fixed a spelling | |
| mistake in "mango", and each removed one fruit to the list. | |
| This makes it more clear how to resolve the merge conflict: since one | |
| side removed `banana` and one side removed `cherry`, it would probably | |
| make sense to remove both from the list, like this: | |
| ---- | |
| FRUITS = [ | |
| "apple", | |
| "mango", | |
| "orange", | |
| ] | |
| ---- | |
| [NOTE] | |
| `zdiff3` is an alternative to `diff3` that makes the merge conflict | |
| shorter by making it more ambiguous. See linkgit:git-config[1] for more. | |
| [[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 |