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 <> 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 <> 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 <> 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 <> 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 <> 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 <> below for more. * `git log --merge -p ` will list all commits which caused the merge conflict for ``, 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 <> 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 <> 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 ..." to unstage) (use "git add ..." 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 <> 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