Add new page on merge conflicts
Subsystems (2)
cover Add new page on merge conflicts
Handling merge conflicts is difficult, and currently Git's guidance on merge conflicts isn't giving users the information they need to navigate the process. As usual, the process I used to write this was to collect comments from Git users on the existing documentation, and then address those issues. I listed the specific issues we're aiming to solve in the first commit message in the series.
This patch series introduces a new manual page, gitmergeconflicts, which explains the process of explaining a merge conflict with examples. It also links to that new page from the commands which can cause merge conflicts, instead of trying to reexplain the process every time.
This is a pretty big change, so here's a list of things I'm still considering in the hopes that it'll help with the discussion:
* I wrote that git commit does the same thing as git merge --continue during a git merge , but I'm not sure if that's always true.
* Not 100% sure that the explanation of diff3 vs zdiff3 is correct
* Right now we're listing git merge, git revert, git rebase, git cherry-pick, and git pull as commands that can cause merge conflicts. I believe that git apply and git am can also result in conflicts when applying a patch, though it's a bit complicated because applying a patch is a different operation than doing a 3-way merge and the tools available for dealing with it are a different. My thought right now is to avoid the issue of applying patches for now (because it's a whole can of worms) and instead just try to not imply that this is necessarily an exhaustive list. Also if/when the git rebase --squash changes land, then we'd need to add git history to this list.
* Instead of creating a new page, I considered using an include to have a "handling merge conflicts" section in git rebase, git merge, etc. Merge conflict resolution is complex and it's very useful to be able to include
examples: this version ended up at ~300 lines and I think that's too big of an include, especially for short man pages like cherry-pick
* Explaining what "ours" and "theirs" mean was one of the hardest parts of writing this. From polling Git users in one of my many informal Mastodon polls about Git, my understanding is that Git users are actually relatively unlikely to actually reason about what "ours" and "theirs" mean when dealing with a merge conflict, and that most people prefer to get more context instead, for example by using a mergetool or by using diff3 or zdiff3. I heard a lot of "I can never remember which is which I so I don't even try". So I put the information about what "ours" and "theirs" mean relatively far down the page (with some cross-references), so that it's easily available but not the main focus.
* I removed a couple of mentions of the various _HEAD references. It's hard for me to know exactly where they belong because I personally have never used MERGE_HEAD, REBASE_HEAD, ORIG_HEAD, CHERRY_PICK_HEAD etc, and I don't know how they're meant to be used. From some quick unscientific polling (at https://social.jvns.ca/@b0rk/117320011885941855), it seems like most Git users have never used them either (and folks who do use a *_HEAD reference mainly seem to use FETCH_HEAD which isn't relevant here), so from that perspective it seems important to avoid emphasizing them too much. The git revert man page doesn't mention REVERT_HEAD and git rebase only mentions REBASE_HEAD in passing. Of course they're all explained in gitrevisions(7) which might be the best place for them.
* I'm still not sure what the SYNOPSIS section is for in a "guide" man page which is not about a specific Git command (what is the user intended to use it for?). I tried to leave it out but the CI said it was required.
Thanks to Lobo, Adam Svahn, Louis Vanier, David Turner, Ben Zanin, Salih, and about 12 others who gave feedback on both the original git merge man page, as well as the proposed improvements.
Julia Evans (7):
[doc] Add new gitmergeconflicts man page
[doc] git-merge: link to new merge conflicts guide [doc] git-rebase: link to new merge conflicts guide [doc] git-revert: link to new merge conflicts guide [doc] git-cherry-pick: link to new merge conflicts guide [doc] git-pull: link to new merge conflicts guide [doc] ignore conflict markers in gitmergeconflicts.adoc
.gitattributes | 1 + Documentation/Makefile | 1 + Documentation/git-cherry-pick.adoc | 23 +-- Documentation/git-merge.adoc | 125 +----------- Documentation/git-pull.adoc | 3 +- Documentation/git-rebase.adoc | 13 +- Documentation/git-revert.adoc | 5 + Documentation/gitmergeconflicts.adoc | 294 +++++++++++++++++++++++++++ Documentation/meson.build | 1 + 9 files changed, 320 insertions(+), 146 deletions(-) create mode 100644 Documentation/gitmergeconflicts.adoc
base-commit: 3bc0341126508f78f5869cbfc0005e987efdf0c7
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2237%2Fjvns%2Fmerge-conflicts-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2237/jvns/merge-conflicts-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/2237
Signature · 1 line
gitgitgadget
PATCH 1/7 Add new gitmergeconflicts man page
From: Julia Evans <[email protected]>
Introduce a new page, gitmergeconflicts, that explains the process of handling a merge conflict in a way that addresses the following issues, which came from feedback from Git users on the current explanation of merge conflicts in the git merge man page:
- The process for resolving a merge conflict is only explained in the git merge man page, even though there are several other commands which can result in conflicts
- Sometimes we use "ours" and "theirs" to refer to the two sides of the merge conflicts and sometimes we use HEAD and MERGE_HEAD. It should be consistent. Also the terms "ours" and "theirs" are not explained. Similarly, it says "The part before the ======= is typically your side...", but doesn't explain what "typically" means.
- It introduces the merge format using an analogy to RCS, which very few Git users have ever used
- In "The only clean-ups you need are to reset the index file to the HEAD commit to reverse 2. and to clean up working tree changes made by 2. and 3.", it's not clear to users what "2" and "3" are supposed to mean
- It uses a cultural reference ("Conflict resolution is hard; let's go shopping.") which is confusing or unfamiliar to some people. I think it would be clearer for users to use a code example instead.
- It doesn't explain the difference between diff3 and zdiff3
- It sometimes uses the term "area" and sometimes uses the term "hunk"
Also document the unified --abort, --continue workflow in one place, since it's a really nice example of a place Git has a consistent interface between similar commands.
--- Documentation/Makefile | 1 + Documentation/gitmergeconflicts.adoc | 294 +++++++++++++++++++++++++++ Documentation/meson.build | 1 + 3 files changed, 296 insertions(+) create mode 100644 Documentation/gitmergeconflicts.adoc
Documentation/Makefile +1 -0
@@ -58,6 +58,7 @@ MAN7_TXT += gitdiffcore.adoc MAN7_TXT += giteveryday.adoc MAN7_TXT += gitfaq.adoc MAN7_TXT += gitglossary.adoc +MAN7_TXT += gitmergeconflicts.adoc MAN7_TXT += gitpacking.adoc MAN7_TXT += gitnamespaces.adoc MAN7_TXT += gitremote-helpers.adoc
Documentation/gitmergeconflicts.adoc new file +294 -0
294 lines not on this page · raw message
Documentation/meson.build +1 -0
@@ -202,6 +202,7 @@ manpages = { 'gitfaq.adoc' : 7, 'gitglossary.adoc' : 7, 'gitpacking.adoc' : 7, + 'gitmergeconflicts.adoc' : 7, 'gitnamespaces.adoc' : 7, 'gitremote-helpers.adoc' : 7, 'gitrevisions.adoc' : 7,
Signature · 1 line
gitgitgadget
Re: [PATCH 1/7] [doc] Add new gitmergeconflicts man page
Quoted 11 lines · Julia Evans via GitGitGadget
Documentation/Makefile | 1 + Documentation/gitmergeconflicts.adoc | 294 +++++++++++++++++++++++++++ Documentation/meson.build | 1 + 3 files changed, 296 insertions(+) create mode 100644 Documentation/gitmergeconflicts.adocDocumentation/Makefile +0
-0
Documentation/Makefile MAN7_TXT += gitdiffcore.adoc · line 61
Quoted 4 lines
Documentation/Makefile +1
-0@@ -58,6 +58,7 @@ MAN7_TXT += gitdiffcore.adoc MAN7_TXT += giteveryday.adoc MAN7_TXT += gitfaq.adoc MAN7_TXT += gitglossary.adoc +MAN7_TXT += gitmergeconflicts.adoc
This unfortunately needs to be accompanied with a matching change to help the other build system.
You probably want to move your change to set conflict-marker-size for this new file to this step, not at the end as if an afterthought.
Documentation/meson.build | 1 + 1 file changed, 1 insertion(+)
Documentation/meson.build +1 -0
@@ -201,6 +201,7 @@ manpages = { 'giteveryday.adoc' : 7, 'gitfaq.adoc' : 7, 'gitglossary.adoc' : 7, + 'gitmergeconflicts.adoc' : 7, 'gitpacking.adoc' : 7, 'gitmergeconflicts.adoc' : 7, 'gitnamespaces.adoc' : 7,
Re: [PATCH 1/7] [doc] Add new gitmergeconflicts man page
Quoted 2 lines · Junio C Hamano
This unfortunately needs to be accompanied with a matching change to help the other build system.
I did get a build failure due to meson, but apparently not due to this step in the 7-patch series.
Quoted 3 lines
You probably want to move your change to set conflict-marker-size for this new file to this step, not at the end as if an afterthought.
This still stands, though.
Sorry, a wrong patch and a false alarm.
Quoted 17 lines
Documentation/meson.build | 1 + 1 file changed, 1 insertion(+)Documentation/meson.build +1
-0@@ -201,6 +201,7 @@ manpages = { 'giteveryday.adoc' : 7, 'gitfaq.adoc' : 7, 'gitglossary.adoc' : 7, + 'gitmergeconflicts.adoc' : 7, 'gitpacking.adoc' : 7, 'gitmergeconflicts.adoc' : 7, 'gitnamespaces.adoc' : 7,
Re: [PATCH 1/7] [doc] Add new gitmergeconflicts man page
In reply to Julia Evans via GitGitGadgetQuoted 14 lines · Julia Evans via GitGitGadget
Documentation/gitmergeconflicts.adoc new file +8
-0@@ -0,0 +1,294 @@ +gitmergeconflicts(7) +==================== + +NAME +---- +gitmergeconflicts - Guide to handling merge conflicts + +
Documentation/gitmergeconflicts.adoc line 18
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+SYNOPSIS +-------- +Guide to handling merge conflicts + + +DESCRIPTION +----------- + +Merge conflicts can happen during a `git merge`, `git rebase`, `git +cherry-pick`, `git pull`, or `git revert`. All of those commands use
Should all of these be using linkgit:, like for example in linkgit:git-merge[1]?
Documentation/gitmergeconflicts.adoc line 20
Quoted 2 lines
Documentation/gitmergeconflicts.adoc new file +2
-0+the same merge algorithm, and the process for resolving a merge conflict +is always very similar.
There's also git-am(1), but only when adding the "--3way" flag. So maybe it's best to ignore that command indeed.
Documentation/gitmergeconflicts.adoc line 29
Quoted 8 lines
Documentation/gitmergeconflicts.adoc new file +8
-0+The most common ways to handle a merge conflict are: + +* Resolve the conflict. (see <<resolve,HOW TO RESOLVE A MERGE CONFLICT>> + below for details) +* Or 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.
I wonder whether the explanation should be expanded a bit to briefly explain how Git performs a 3-way merge in the first place. I feel like it's quite important to understand what the three different sides of the merge are to make sense of it.
But I may be too far detached from the "normal" user, so this may only cause more confusion for our users.
Documentation/gitmergeconflicts.adoc line 37
Quoted 6 lines
Documentation/gitmergeconflicts.adoc new file +6
-0+[[markers]] +MERGE CONFLICT MARKERS +---------------------- + +Merge conflicts happen when both of the sides being merged edit the same +area of a file. When this happens, Git will update the conflicted file
I wonder whether we want to use "hunk" instead of "area". It's jargon again, but I have never heard anybody speak about an "area" before myself.
Documentation/gitmergeconflicts.adoc line 49
Quoted 12 lines
Documentation/gitmergeconflicts.adoc new file +12
-0+to include merge conflict markers `<<<<<<<`, `=======`, and `>>>>>>>`. +For example, here's a merge conflict where both sides edited a list of +fruits in different ways: + +---- +FRUITS = [ + "apple", +<<<<<<< HEAD + "cherry", +======= + "banana", +>>>>>>> add-fruit
A bit of a tangent, but sometimes I wonder whether we should make the respective commits a bit easier to access. For example, we could put the equivalent of git rev-parse --reference <commit> here for each of the sides.
Quoted 19 lines
Documentation/gitmergeconflicts.adoc new file +19
-0+ "mango", + "orange", +] +---- + +The code from one side of the merge conflict is between `<<<<<<<` and +`=======`, and the code for 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
Documentation/gitmergeconflicts.adoc line 78
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+ (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 the same thing.
s/the the/the/
Maybe we should also say "During a conflicted git merge.", but maybe that's redundant.
Quoted 12 lines
Documentation/gitmergeconflicts.adoc new file +12
-0+[[example]] +EXAMPLE OF RESOLVING A MERGE CONFLICT +------------------------------------- + +If you see this in your code during a merge conflict: + +---- +FRUITS = [ + "apple", +<<<<<<< HEAD + "cherry", + "mango",
Documentation/gitmergeconflicts.adoc line 102
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+======= + "banana", + "mango", +>>>>>>> add-fruit + "orange", +] +---- + +Then you might edit that part of the code like this, +which includes the fruits from both sides of the conflict:
I tend to forget that by default, we only render ours/theirs in the conflict. I always feel like that makes it way harder to resolve conflicts as you don't have the context of what the code looked like originally. So I have diff3 configured locally for ages.
Quoted 12 lines
Documentation/gitmergeconflicts.adoc new file +12
-0+---- +FRUITS = [ + "apple", + "banana", + "cherry", + "mango", + "orange", +] +---- + + +[[tools]]
Documentation/gitmergeconflicts.adoc line 125
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+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.
There's also git merge-tool --tool-help to list all available drivers.
[snip]
Documentation/gitmergeconflicts.adoc line 183
Quoted 9 lines
Documentation/gitmergeconflicts.adoc new file +9
-0+[[diff3]] +DIFF3 AND ZDIFF3 +---------------- + +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` or `zdiff3`. +This extra context can make it much easier to understand what's +happening in a merge conflict.
Indeed.
[snip]
Quoted 5 lines
Documentation/gitmergeconflicts.adoc new file +5
-0+[[ours]] +"OURS" AND "THEIRS" +------------------- + +Git refers to the first part of a merge conflict (between `<<<<<<<`
Documentation/gitmergeconflicts.adoc line 243
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+and `=======`) as "ours" and the second part (between `=======` and +`>>>>>>>`) as "theirs". + +Normally, "ours" is the commit that was checked out before you started +the merge, and "theirs" is the other commit. + +But when the merge conflict was caused by a `git rebase`, it's the +opposite: "theirs" is the commit that was checked out before you started +the merge. This is because under the hood, `git rebase main` checks out +the `main` commit first before doing the merge operation.
Hmm. This part is a bit confusing to me. "ours" is always the commit that's currently checked out, and "theirs" is always the one that is getting merged into the checked-out commit.
How about a variant of the following instead?
In a conflict, the side between <<<<<<< and ======= is "ours" and the side between ======= and >>>>>>> is "theirs". "Ours" is always the side that HEAD points to while the merge happens; "theirs" is the commit being merged into it.
For git merge <other>, HEAD is your current branch, so "ours" is your branch and "theirs" is <other>.
For git rebase <upstream>, HEAD is first moved to <upstream> and your commits are then replayed on top one at a time. So "ours" is the already-rebased history starting at <upstream>, and "theirs" is the commit from your original branch that is currently being replayed.
Documentation/gitmergeconflicts.adoc line 250
Quoted 6 lines
Documentation/gitmergeconflicts.adoc new file +6
-0+These terms in Git all mean the same thing when dealing with a merge +conflict: + +* "common ancestor", "base", and "stage 1" +* "ours", "us", "stage 2", and `HEAD` +* "theirs", "them", and "stage 3"
I wouldn't say that "stage N" is equivalent to the respective other terms. These stages rather refer to the different versions of a specific file as recorded in the index, they do not indicate a specific commit. In contrast to that, all the other terms may also indicate a specific version of a file, but may also refer to the commits.
Patrick
Re: [PATCH 1/7] [doc] Add new gitmergeconflicts man page
Quoted 5 lines
Documentation/gitmergeconflicts.adoc line 18
Quoted 2 lines
Documentation/gitmergeconflicts.adoc new file +2
-0+Merge conflicts can happen during a `git merge`, `git rebase`, `git +cherry-pick`, `git pull`, or `git revert`. All of those commands useShould all of these be using linkgit:, like for example in linkgit:git-merge[1]?
Makes sense to me, will change.
Quoted 14 lines
Documentation/gitmergeconflicts.adoc line 29
Quoted 8 lines
Documentation/gitmergeconflicts.adoc new file +8
-0+The most common ways to handle a merge conflict are: + +* Resolve the conflict. (see <<resolve,HOW TO RESOLVE A MERGE CONFLICT>> + below for details) +* Or 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.I wonder whether the explanation should be expanded a bit to briefly explain how Git performs a 3-way merge in the first place. I feel like it's quite important to understand what the three different sides of the merge are to make sense of it.
Quoted 2 lines
But I may be too far detached from the "normal" user, so this may only cause more confusion for our users.
I think it would cause more confusion. I did some experiments in explaining merge conflicts using the concept of 3-way merge a couple of years ago and it didn't go well.
My experience was that what users they found the most useful was learning about the tools Git offers (like git diff --check and diff3), so that's why this document focuses on tools and formatting much more than concepts.
I think it would be cool to find a way to explain how 3-way merge works at in this document in some later iteration though, maybe at the end. Definitely some folks would find it interesting. I didn't understand 3-way merge myself until a couple of years ago and it was fun for me to learn, but it didn't really help me use Git effectively.
(this is quickly becoming a bit of a novel, but it's often very counterintuitive how some facts that seem "fundamental" about how Git works actually turn out to not be very important to understand in practice to use it effectively. It's something I find tough to talk about on this mailing list because it's something I've only been able to learn empirically)
Quoted 10 lines
Documentation/gitmergeconflicts.adoc line 37
Quoted 6 lines
+[[markers]]
Documentation/gitmergeconflicts.adoc new file +5
-0+MERGE CONFLICT MARKERS +---------------------- + +Merge conflicts happen when both of the sides being merged edit the same +area of a file. When this happens, Git will update the conflicted fileI wonder whether we want to use "hunk" instead of "area". It's jargon again, but I have never heard anybody speak about an "area" before myself.
Ah thanks, I think I took "area" from the git-merge man page.
I looked up how I explained this previously and I used "lines of code", which I think communicates the same meaning without the jargon. I'll try that instead.
Quoted 4 lines
Documentation/gitmergeconflicts.adoc line 78
Quoted 2 lines
Documentation/gitmergeconflicts.adoc new file +2
-0+Note: During a `git merge`, `git commit` and `git merge --continue` do +the the same thing.s/the the/the/
Will fix.
Quoted 14 lines
Documentation/gitmergeconflicts.adoc line 49
Quoted 12 lines
Documentation/gitmergeconflicts.adoc new file +12
-0+to include merge conflict markers `<<<<<<<`, `=======`, and `>>>>>>>`. +For example, here's a merge conflict where both sides edited a list of +fruits in different ways: + +---- +FRUITS = [ + "apple", +<<<<<<< HEAD + "cherry", +======= + "banana", +>>>>>>> add-fruitHide quoted text
Quoted 4 lines
A bit of a tangent, but sometimes I wonder whether we should make the respective commits a bit easier to access. For example, we could put the equivalent of
git rev-parse --reference <commit>here for each of the sides.
Personally I'm not sure if the commit ID would do much for me, but I feel like it would help me if it were possible to include the commit message.
Quoted 4 lines
I tend to forget that by default, we only render ours/theirs in the conflict. I always feel like that makes it way harder to resolve conflicts as you don't have the context of what the code looked like originally. So I have diff3 configured locally for ages.
Every time I show people diff3 someone tells me how happy they are to learn it :)
Quoted 7 lines
Documentation/gitmergeconflicts.adoc line 125
Quoted 5 lines
Documentation/gitmergeconflicts.adoc new file +5
-0+* 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.There's also
git merge-tool --tool-helpto list all available drivers.
Oh, cool! It's fun that it autodetects which ones you have installed on your system. I'll suggest that.
Quoted 29 lines
[snip]
Quoted 5 lines
+[[ours]]
+"OURS" AND "THEIRS"
+-------------------Documentation/gitmergeconflicts.adoc new file +2
-0+ +Git refers to the first part of a merge conflict (between `<<<<<<<`Documentation/gitmergeconflicts.adoc line 243
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+and `=======`) as "ours" and the second part (between `=======` and +`>>>>>>>`) as "theirs". + +Normally, "ours" is the commit that was checked out before you started +the merge, and "theirs" is the other commit. + +But when the merge conflict was caused by a `git rebase`, it's the +opposite: "theirs" is the commit that was checked out before you started +the merge. This is because under the hood, `git rebase main` checks out +the `main` commit first before doing the merge operation.Hmm. This part is a bit confusing to me. "ours" is always the commit that's currently checked out, and "theirs" is always the one that is getting merged into the checked-out commit.
How about a variant of the following instead?
In a conflict, the side between
<<<<<<<and=======is "ours" and the side between=======and>>>>>>>is "theirs". "Ours" is always the side thatHEADpoints to while the merge happens; "theirs" is the commit being merged into it.
Quoted 7 lines
For
git merge <other>,HEADis your current branch, so "ours" is your branch and "theirs" is<other>.For
git rebase <upstream>,HEADis first moved to<upstream>and your commits are then replayed on top one at a time. So "ours" is the already-rebased history starting at<upstream>, and "theirs" is the commit from your original branch that is currently being replayed.
Thanks, your suggestion gives me some other ways to think about this.
I think I'll try to write something shorter that is unambiguous, instead of trying to use more words to make it feel more intuitive. I don't think I actually know anyone who feels it's easy to understand the way merge conflicts are presented, and more explanation may not help.
It might be more useful here to encourage (again) folks to use one of the many amazing tools available (in the "tools" section) to get more context.
Quoted 4 lines
Quoted 4 lines
Documentation/gitmergeconflicts.adoc new file +4
-0+These terms in Git all mean the same thing when dealing with a merge +conflict: + +* "common ancestor", "base", and "stage 1"
Quoted 8 lines
Documentation/gitmergeconflicts.adoc line 250
Quoted 2 lines
Documentation/gitmergeconflicts.adoc new file +2
-0+* "ours", "us", "stage 2", and `HEAD` +* "theirs", "them", and "stage 3"I wouldn't say that "stage N" is equivalent to the respective other terms. These stages rather refer to the different versions of a specific file as recorded in the index, they do not indicate a specific commit. In contrast to that, all the other terms may also indicate a specific version of a file, but may also refer to the commits.
Thanks, will try to figure out how to make it more accurate. We could also refer to gitdatamodel if folks want to learn what the term "stage" means too.
Thanks for the review!
- Julia
Re: [PATCH 1/7] [doc] Add new gitmergeconflicts man page
Quoted 14 lines · Julia Evans
Quoted 14 lines
Documentation/gitmergeconflicts.adoc line 49
Quoted 12 lines
Documentation/gitmergeconflicts.adoc new file +12
-0+to include merge conflict markers `<<<<<<<`, `=======`, and `>>>>>>>`. +For example, here's a merge conflict where both sides edited a list of +fruits in different ways: + +---- +FRUITS = [ + "apple", +<<<<<<< HEAD + "cherry", +======= + "banana", +>>>>>>> add-fruitHide quoted text
Quoted 7 lines
Quoted 4 lines
A bit of a tangent, but sometimes I wonder whether we should make the respective commits a bit easier to access. For example, we could put the equivalent of
git rev-parse --reference <commit>here for each of the sides.Personally I'm not sure if the commit ID would do much for me, but I feel like it would help me if it were possible to include the commit message.
It would also help the resolution, not just committing after you are done. It may not matter while picking between cherry and banana to show your personal preference on fruits, but in a more involved conflicted merge, it may help to be able to view "git show $commit", "git diff ...$commit", and "git diff $commit..." where $commit is the "add-fruit" side of the merge to understand what they wanted to do, and what we have done while they weren't looking.
Quoted 7 lines
Quoted 4 lines
I tend to forget that by default, we only render ours/theirs in the conflict. I always feel like that makes it way harder to resolve conflicts as you don't have the context of what the code looked like originally. So I have diff3 configured locally for ages.
Every time I show people diff3 someone tells me how happy they are to learn it :)
Yes, we should encourage "merge.conflictstyle=diff3" (I feel about this strongly enough to think it should become the default). Knowing what the original was before one side wanted to say "cherry" while the other side wanted to say "banana" sometimes helps a great deal to decide what to do with the conflict.
Re: [PATCH 1/7] [doc] Add new gitmergeconflicts man page
Quoted 24 lines · Junio C Hamano
Quoted 14 lines · Julia Evans
Quoted 14 lines
Documentation/gitmergeconflicts.adoc line 49
Quoted 12 lines
Documentation/gitmergeconflicts.adoc new file +12
-0+to include merge conflict markers `<<<<<<<`, `=======`, and `>>>>>>>`. +For example, here's a merge conflict where both sides edited a list of +fruits in different ways: + +---- +FRUITS = [ + "apple", +<<<<<<< HEAD + "cherry", +======= + "banana", +>>>>>>> add-fruitHide quoted text
Quoted 7 lines
Quoted 4 lines
A bit of a tangent, but sometimes I wonder whether we should make the respective commits a bit easier to access. For example, we could put the equivalent of
git rev-parse --reference <commit>here for each of the sides.Personally I'm not sure if the commit ID would do much for me, but I feel like it would help me if it were possible to include the commit message.
Quoted 7 lines
It would also help the resolution, not just committing after you are done. It may not matter while picking between cherry and banana to show your personal preference on fruits, but in a more involved conflicted merge, it may help to be able to view "git show $commit", "git diff ...$commit", and "git diff $commit..." where $commit is the "add-fruit" side of the merge to understand what they wanted to do, and what we have done while they weren't looking.
Yup. Doesn't mean we cannot _also_ include the names that we have above. So in the above example it could be for example:
+FRUITS = [
+ "apple",
+<<<<<<< HEAD: abcdefg (fruits: add apple, 2026-10-01)
+ "cherry",
+======= + "banana",
+>>>>>>> add-fruit: 12345678 (fruits: add banana, 2024-02-03)
That format would have a bunch of advantages:
- We don't have to teach users about special refs like MERGE_HEAD to let them figure out how to access each of the commits.
- It gives a bit more context about what each specific side does, at least if you have good commit messages.
- It also gives a sense of timing because we include dates, and that may help in some situations to figure out what's what.
I'll create an issue on the GitLab side and ask someone in the team to maybe give this a try.
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
I tend to forget that by default, we only render ours/theirs in the conflict. I always feel like that makes it way harder to resolve conflicts as you don't have the context of what the code looked like originally. So I have diff3 configured locally for ages.
Quoted 8 lines
Quoted 2 lines
Every time I show people diff3 someone tells me how happy they are to learn it :)
Yes, we should encourage "merge.conflictstyle=diff3" (I feel about this strongly enough to think it should become the default). Knowing what the original was before one side wanted to say "cherry" while the other side wanted to say "banana" sometimes helps a great deal to decide what to do with the conflict.
I very much agree that it should be the default.
Patrick
Re: [PATCH 1/7] [doc] Add new gitmergeconflicts man page
Quoted 11 lines
Documentation/gitmergeconflicts.adoc new file +7
-0+FRUITS = [ + "apple", +<<<<<<< HEAD: abcdefg (fruits: add apple, 2026-10-01) + "cherry", +======= + "banana", +>>>>>>> add-fruit: 12345678 (fruits: add banana, 2024-02-03)That format would have a bunch of advantages:
Quoted 8 lines
- We don't have to teach users about special refs like
MERGE_HEADto let them figure out how to access each of the commits.- It gives a bit more context about what each specific side does, at least if you have good commit messages.
- It also gives a sense of timing because we include dates, and that may help in some situations to figure out what's what.
This is so cool, I love the idea of including the dates and the commit messages!!! I think this would be very helpful for the reasons you say.
Though re "We don't have to teach users about special refs like MERGE_HEAD": I think that users today could rungit show HEAD or git show add-fruit to see the commits on each side? I've never used MERGE_HEAD though so maybe I'm misunderstanding what it does. I think adding the commit ID makes it clearer too.
I just ran downstairs to show my partner this example at 8am because I was so excited about it :) (he liked it too)
Re: [PATCH 1/7] [doc] Add new gitmergeconflicts man page
In reply to Junio C HamanoQuoted 8 lines · Junio C Hamano
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Documentation/gitmergeconflicts.adoc new file +7
-0+FRUITS = [ + "apple", +<<<<<<< HEAD + "cherry", +======= + "banana", +>>>>>>> add-fruit
Quoted 8 lines
Quoted 2 lines
Every time I show people diff3 someone tells me how happy they are to learn it :)
Yes, we should encourage "merge.conflictstyle=diff3" (I feel about this strongly enough to think it should become the default). Knowing what the original was before one side wanted to say "cherry" while the other side wanted to say "banana" sometimes helps a great deal to decide what to do with the conflict.
Before I forget, here is a good illustration to tell why diff3 style is often essential to correct conflict resolution that we can tell new users. You may want to throw it in to your new manual pages.
If the conflict looks like this
FRUITS = [
"apple",
<<<<<<< HEAD
"cherry",
|||||||
=======
"banana",
>>>>>>> add-fruitthen we can tell that in the beginning there was only 'apple', and one side wanted to add 'cherry', while the other side wanted to add 'banana'. It is likely that we would make both sides happy by adding both of them.
But on the other hand, if the conflict looks like this
FRUITS = [
"apple",
<<<<<<< HEAD
"cherry",
|||||||
"banana",
"cherry",
=======
"banana",
>>>>>>> add-fruitwe can tell that before two sides started editing, we had 'apple', 'banana', and 'cherry'. While both wanted to keep 'apple', one side did not want 'banana', and the other side did not want 'cherry'. It is plausible that we can please both of them by removing these two.
With just two-sides, the user who is trying to resolve the conflict cannot tell the difference.
Re: [PATCH 1/7] [doc] Add new gitmergeconflicts man page
In reply to Julia EvansQuoted 62 lines
Quoted 29 lines
[snip]
Quoted 5 lines
+[[ours]]
+"OURS" AND "THEIRS"
+-------------------Documentation/gitmergeconflicts.adoc new file +2
-0+ +Git refers to the first part of a merge conflict (between `<<<<<<<`Documentation/gitmergeconflicts.adoc line 243
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+and `=======`) as "ours" and the second part (between `=======` and +`>>>>>>>`) as "theirs". + +Normally, "ours" is the commit that was checked out before you started +the merge, and "theirs" is the other commit. + +But when the merge conflict was caused by a `git rebase`, it's the +opposite: "theirs" is the commit that was checked out before you started +the merge. This is because under the hood, `git rebase main` checks out +the `main` commit first before doing the merge operation.Hmm. This part is a bit confusing to me. "ours" is always the commit that's currently checked out, and "theirs" is always the one that is getting merged into the checked-out commit.
How about a variant of the following instead?
In a conflict, the side between
<<<<<<<and=======is "ours" and the side between=======and>>>>>>>is "theirs". "Ours" is always the side thatHEADpoints to while the merge happens; "theirs" is the commit being merged into it.Quoted 7 lines
For
git merge <other>,HEADis your current branch, so "ours" is your branch and "theirs" is<other>.For
git rebase <upstream>,HEADis first moved to<upstream>and your commits are then replayed on top one at a time. So "ours" is the already-rebased history starting at<upstream>, and "theirs" is the commit from your original branch that is currently being replayed.Thanks, your suggestion gives me some other ways to think about this.
I think I'll try to write something shorter that is unambiguous, instead of trying
to use more words to make it feel more intuitive. I don't think I actually know
anyone who feels it's easy to understand the way merge conflicts are presented, and more explanation may not help.It might be more useful here to encourage (again) folks to use one of the many amazing tools available (in the "tools" section) to get more context.
Quoted 4 lines
Quoted 4 lines
Documentation/gitmergeconflicts.adoc new file +4
-0+These terms in Git all mean the same thing when dealing with a merge +conflict: + +* "common ancestor", "base", and "stage 1"Quoted 8 lines
Documentation/gitmergeconflicts.adoc line 250
Quoted 2 lines
Documentation/gitmergeconflicts.adoc new file +2
-0+* "ours", "us", "stage 2", and `HEAD` +* "theirs", "them", and "stage 3"I wouldn't say that "stage N" is equivalent to the respective other terms. These stages rather refer to the different versions of a specific file as recorded in the index, they do not indicate a specific commit. In contrast to that, all the other terms may also indicate a specific version of a file, but may also refer to the commits.
Quoted 3 lines
Thanks, will try to figure out how to make it more accurate. We could also refer to gitdatamodel if folks want to learn what the term "stage" means too.
Marie and I worked on the OURS AND THEIRS section today and I think it's clearer now but also longer (instead of shorter which was my dream). We added an attempt at humor at the end to hopefully help things a bit.
"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.
Re: [PATCH 1/7] [doc] Add new gitmergeconflicts man page
Quoted 42 lines · Julia Evans
Marie and I worked on the OURS AND THEIRS section today and I think it's clearer now but also longer (instead of shorter which was my dream). We added an attempt at humor at the end to hopefully help things a bit.
"OURS" AND "THEIRS"
-------------------Sometimes during a merge conflict, Git will use the terms "ours" and "theirs" (or "us" and "them"). For example,
git statusmight say that a file wasdeleted by us."Ours" and "theirs" are both commits: "ours" is the current
HEADcommit, 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
mainingit 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", andHEAD. The files from this commit are "in stage 2".
* "theirs", "them". The files from this commit are "in stage 3".
Quoted 5 lines
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.
May I ask what is in scope for this effort?
We previously discussed updating the conflict markers (the 'HEAD' and 'add-fruit' labels in the example above). Doing so would require code changes, which goes beyond mere documentation updates. But if a minor code change like that makes the documentation much easier to understand, I think we should consider doing so.
Along the same line, if git status stopped saying "deleted by us" and instead used a different phrase, would that help reduce the "upside down" confusion [*]? Is it acceptable to bend the code a little if it helps the documentation?
[Footnote]
* I suspect that the "upside down" feeling is not really about the terms "ours" and "theirs" themselves. Rather, it comes from how one conceptualizes what 'rebase' does compared to 'merge'. During a rebase, we temporarily pretend that we are working on the upstream branch and replay our local changes on top of it. Once the user adopts this mindset, displaying the upstream state first (the point from which we start building the consolidated history) followed by the local state (what was done differently by the local side) becomes consistent with how 'merge' displays conflicts (where we start from our local state and merge the incoming changes).
Re: [PATCH 1/7] [doc] Add new gitmergeconflicts man page
Quoted 25 lines
Quoted 11 lines
During a rebase, it can seem "upside down" because the "ours" commit is from the branch you're rebasing on (for instance
mainingit 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", andHEAD. The files from this commit are "in stage 2".
* "theirs", "them". The files from this commit are "in stage 3".Quoted 5 lines
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.May I ask what is in scope for this effort?
We previously discussed updating the conflict markers (the 'HEAD' and 'add-fruit' labels in the example above). Doing so would require code changes, which goes beyond mere documentation updates. But if a minor code change like that makes the documentation much easier to understand, I think we should consider doing so.
Quoted 4 lines
Along the same line, if git status stopped saying "deleted by us" and instead used a different phrase, would that help reduce the "upside down" confusion [*]? Is it acceptable to bend the code a little if it helps the documentation?
I agree that would make sense. I have some changes to advice (on other areas) in local branches on my machine already :)
I think of it as sort of "documentation driven development" (write the documentation, and if it feels upsetting what the documentation is saying, then try to change the code so we're happier with the docs!)
I don't have a clear idea for how to improve the way git status presents merge conflicts to make it less confusing right now though.
Brainstorming a bit, here's some commentary on this git status output:
On branch main
Your branch and 'origin/main' have diverged,
and have 2 and 1 different commits each, respectively.
(use "git pull" if you want to integrate the remote branch with yours)
You have unmerged paths.
(fix conflicts and run "git commit") (use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: fruits.py
no changes added to commit (use "git add" and/or "git commit -a")
1. (use "git pull" if you want to integrate the remote branch with yours) is not helpful advice here, it's not even allowed to run git pull in the middle of a merge conflict.
2. git add is sort of not helpful here, all of the unmerged files currently have conflict markers, so the next step is definitely not to run git add, it's to edit one of the unmerged files. But perhaps it's unrealistic to be running the equivalent of git diff --check in git status just to help users out.
3. Not sure if "unmerged" is the best term here, maybe "conflicted"?
4. It gives the advice to use git add twice which is weird.
5. One part of the advice refers to the process of fixing conflicts as "fix conflicts" but the other part calls it "mark resolution". Should probably be consistent there.
But as you can see those comments are all over the place, some of them are just wording changes, some of them would involve adding a bunch of conditional logic to the advice system that might not be realistic, I don't know.
Quoted 13 lines
[Footnote]
* I suspect that the "upside down" feeling is not really about the terms "ours" and "theirs" themselves. Rather, it comes from how one conceptualizes what 'rebase' does compared to 'merge'. During a rebase, we temporarily pretend that we are working on the upstream branch and replay our local changes on top of it. Once the user adopts this mindset, displaying the upstream state first (the point from which we start building the consolidated history) followed by the local state (what was done differently by the local side) becomes consistent with how 'merge' displays conflicts (where we start from our local state and merge the incoming changes).
I will say that I know all of these facts but it has never helped me to remember "ours" and "theirs" :). I'm pretty resistant in general to telling people they need to adopt the "right mindset", IMO it's normal for people to have different points of view.
When explaining Git I heard a lot of "yes I know all that but I just don't like to think about it that way" and it really helped me to learn to respect when folks said that and try to see it from their point of view.
PATCH 2/7 git-merge: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
All of the info about merge conflicts has been moved to the new guide
--- Documentation/git-merge.adoc | 125 +---------------------------------- 1 file changed, 3 insertions(+), 122 deletions(-)
Documentation/git-merge.adoc +3 -122
@@ -49,7 +49,8 @@ a log message from the user describing the changes. Before the operation, A merge stops if there's a conflict that cannot be resolved automatically or if `--no-commit` was provided when initiating the merge. At that point you can run `git merge --abort` or `git merge ---continue`. +--continue`. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts. `git merge --abort` will abort the merge process and try to reconstruct the pre-merge state. However, if there were uncommitted changes when the
@@ -231,127 +232,6 @@ git merge v1.2.3^0 git merge --ff-only v1.2.3 ---- -HOW CONFLICTS ARE PRESENTED ---------------------------- - -During a merge, the working tree files are updated to reflect the result -of the merge. Among the changes made to the common ancestor's version, -non-overlapping ones (that is, you changed an area of the file while the -other side left that area intact, or vice versa) are incorporated in the -final result verbatim. When both sides made changes to the same area, -however, Git cannot randomly pick one side over the other, and asks you to -resolve it by leaving what both sides did to that area. - -By default, Git uses the same style as the one used by the "merge" program -from the RCS suite to present such a conflicted hunk, like this: - ------------- -Here are lines that are either unchanged from the common -ancestor, or cleanly resolved because only one side changed, -or cleanly resolved because both sides changed the same way. -<<<<<<< yours:sample.txt -Conflict resolution is hard; -let's go shopping. -======= -Git makes conflict resolution easy. ->>>>>>> theirs:sample.txt -And here is another line that is cleanly resolved or unmodified. ------------- - -The area where a pair of conflicting changes happened is marked with markers -+<<<<<<<+, `=======`, and +>>>>>>>+. The part before the `=======` -is typically your side, and the part afterwards is typically their side. - -The default format does not show what the original said in the conflicting -area. You cannot tell how many lines are deleted and replaced with -Barbie's remark on your side. The only thing you can tell is that your -side wants to say it is hard and you'd prefer to go shopping, while the -other side wants to claim it is easy. - -An alternative style can be used by setting the `merge.conflictStyle` -configuration variable to either `diff3` or `zdiff3`. In `diff3` -style, the above conflict may look like this: - ------------- -Here are lines that are either unchanged from the common -ancestor, or cleanly resolved because only one side changed, -<<<<<<< yours:sample.txt -or cleanly resolved because both sides changed the same way. -Conflict resolution is hard; -let's go shopping. -||||||| base:sample.txt -or cleanly resolved because both sides changed identically. -Conflict resolution is hard. -======= -or cleanly resolved because both sides changed the same way. -Git makes conflict resolution easy. ->>>>>>> theirs:sample.txt -And here is another line that is cleanly resolved or unmodified. ------------- - -while in `zdiff3` style, it may look like this: - ------------- -Here are lines that are either unchanged from the common -ancestor, or cleanly resolved because only one side changed, -or cleanly resolved because both sides changed the same way. -<<<<<<< yours:sample.txt -Conflict resolution is hard; -let's go shopping. -||||||| base:sample.txt -or cleanly resolved because both sides changed identically. -Conflict resolution is hard. -======= -Git makes conflict resolution easy. ->>>>>>> theirs:sample.txt -And here is another line that is cleanly resolved or unmodified. ------------- - -In addition to the +<<<<<<<+, `=======`, and +>>>>>>>+ markers, it uses -another +|||||||+ marker that is followed by the original text. You can -tell that the original just stated a fact, and your side simply gave in to -that statement and gave up, while the other side tried to have a more -positive attitude. You can sometimes come up with a better resolution by -viewing the original. - - -HOW TO RESOLVE CONFLICTS ------------------------- - -After seeing a conflict, you can do two things: - - * Decide not to merge. The only clean-ups you need are to reset - the index file to the `HEAD` commit to reverse 2. and to clean - up working tree changes made by 2. and 3.; `git merge --abort` - can be used for this. - - * Resolve the conflicts. Git will mark the conflicts in - the working tree. Edit the files into shape and - `git add` them to the index. Use `git commit` or - `git merge --continue` to seal the deal. The latter command - checks whether there is a (interrupted) merge in progress - before calling `git commit`. - -You can work through the conflict with a number of tools: - - * Use a mergetool. `git mergetool` to launch a graphical - mergetool which will work through the merge with you. - - * Look at the diffs. `git diff` will show a three-way diff, - highlighting changes from both the `HEAD` and `MERGE_HEAD` - versions. `git diff AUTO_MERGE` will show what changes you've - made so far to resolve textual conflicts. - - * Look at the diffs from each branch. `git log --merge -p <path>` - will show diffs first for the `HEAD` version and then the - `MERGE_HEAD` version. - - * Look at the originals. `git show :1:filename` shows the - common ancestor, `git show :2:filename` shows the `HEAD` - version, and `git show :3:filename` shows the `MERGE_HEAD` - version. - - EXAMPLES --------
@@ -406,6 +286,7 @@ linkgit:git-reset[1], linkgit:git-diff[1], linkgit:git-ls-files[1], linkgit:git-add[1], linkgit:git-rm[1], linkgit:git-mergetool[1] +linkgit:gitmergeconflicts[7] GIT ---
Signature · 1 line
gitgitgadget
Re: [PATCH 2/7] [doc] git-merge: link to new merge conflicts guide
Hi Julia,
Quoted 6 lines · Julia Evans via GitGitGadget
From: Julia Evans <[email protected]>
All of the info about merge conflicts has been moved to the new guide
Among the changes made to the common ancestor's version,
Documentation/git-merge.adoc git merge v1.2.3^0
Quoted 9 lines
Documentation/git-merge.adoc +0
-8-non-overlapping ones (that is, you changed an area of the file while the -other side left that area intact, or vice versa) are incorporated in the -final result verbatim. When both sides made changes to the same area, -however, Git cannot randomly pick one side over the other, and asks you to -resolve it by leaving what both sides did to that area. - * Look at the diffs from each branch. `git log --merge -p <path>` - will show diffs first for the `HEAD` version and then the - `MERGE_HEAD` version.
I think these are both valuable pieces of information we have lost in the new guide (unless I misremember just having read patch 1 :).
The first explains a bit more about what a conflict *is*. Maybe that's old-hat nowadays, but I think it could be nice to keep a statement about why conflicts exist.
The second is a very useful way to get more context to help resolve conflicts! I have an alias "conflict = log --oneline --graph --left-right --boundary --merge" for a similar purpose, and I think the new guide should help folks discover --merge. Often I can get a better sense of how to resolve conflicts by comparing the original changes on each side, or I might at least know who to ask about what to do.
Signature · 1 line
D. Ben Knoble
Re: [PATCH 2/7] [doc] git-merge: link to new merge conflicts guide
Quoted 20 lines · D. Ben Knoble
Hi Julia,
Quoted 6 lines · Julia Evans via GitGitGadget
From: Julia Evans <[email protected]>
All of the info about merge conflicts has been moved to the new guide
Among the changes made to the common ancestor's version,
Documentation/git-merge.adoc git merge v1.2.3^0
Quoted 9 lines
Documentation/git-merge.adoc +0
-8-non-overlapping ones (that is, you changed an area of the file while the -other side left that area intact, or vice versa) are incorporated in the -final result verbatim. When both sides made changes to the same area, -however, Git cannot randomly pick one side over the other, and asks you to -resolve it by leaving what both sides did to that area. - * Look at the diffs from each branch. `git log --merge -p <path>` - will show diffs first for the `HEAD` version and then the - `MERGE_HEAD` version.
Quoted 6 lines
I think these are both valuable pieces of information we have lost in the new guide (unless I misremember just having read patch 1 :).
The first explains a bit more about what a conflict *is*. Maybe that's old-hat nowadays, but I think it could be nice to keep a statement about why conflicts exist.
Will think about this!
Quoted 7 lines
The second is a very useful way to get more context to help resolve conflicts! I have an alias "conflict = log --oneline --graph --left-right --boundary --merge" for a similar purpose, and I think the new guide should help folks discover --merge. Often I can get a better sense of how to resolve conflicts by comparing the original changes on each side, or I might at least know who to ask about what to do.
Thanks, I meant to flag this: the reason I deleted it was really just that I couldn't understand what git log --merge -p <path> did from the documentation and so I removed it until I could figure it out. I thought that --merge meant that it had something to do with merge commits, but upon further investigation it looks like that's not true, and that --merges is related to merge commits, --merge is something totally different which is relevant any time there's a conflict
My best guess now is that it would make sense to include this under "Tools to get more context". Maybe something like this:
Quoted 3 lines
git log --merge -p <filename>will print out all commits which
caused the merge conflict for<filename>, and the diff
of how they changed the file.
("which caused the merge conflict for" is a little more vague, but I'm trying to convey the intent, and hopefully folks can look at man git log if they want to know the specifics)
This does sound really useful.
Re: [PATCH 2/7] [doc] git-merge: link to new merge conflicts guide
Quoted 3 lines · Julia Evans
Thanks, I meant to flag this: the reason I deleted it was really just that I couldn't understand what
git log --merge -p <path>did from the documentation and so I removed it until I could figure it out.
It looks at the index to figure out which paths we got conflicts on, and then does "git log -p <those> <conflicted> <paths>". You can give a pathspec from the command line to further limit the output.
Quoted 3 lines
Quoted 3 lines
git log --merge -p <filename>will print out all commits which
caused the merge conflict for<filename>, and the diff
of how they changed the file.
If you _know_ which exact single file you are interested in, there is not much you gain from the "--merge" option. "--left-right" option may be a lot more useful there. It let's you see which side of the merge gave you what changes.
Re: [PATCH 2/7] [doc] git-merge: link to new merge conflicts guide
Quoted 12 lines · Junio C Hamano
Quoted 3 lines · "Julia Evans
Thanks, I meant to flag this: the reason I deleted it was really just that I couldn't understand what
git log --merge -p <path>did from the documentation and so I removed it until I could figure it out.It looks at the index to figure out which paths we got conflicts on, and then does "git log -p <those> <conflicted> <paths>". You can give a pathspec from the command line to further limit the output.
This explanation omits the manual’s “HEAD…<other>” argument that the merge option implies, which is important for understanding the option and my alias ;)
Re: [PATCH 2/7] [doc] git-merge: link to new merge conflicts guide
Quoted 8 lines · Ben Knoble
Quoted 8 lines · Junio C Hamano
Quoted 3 lines · "Julia Evans
Thanks, I meant to flag this: the reason I deleted it was really just that I couldn't understand what
git log --merge -p <path>did from the documentation and so I removed it until I could figure it out.
Quoted 7 lines
Quoted 3 lines
It looks at the index to figure out which paths we got conflicts on, and then does "git log -p <those> <conflicted> <paths>". You can give a pathspec from the command line to further limit the output.
This explanation omits the manual’s “HEAD…<other>” argument that the merge option implies, which is important for understanding the option and my alias ;)
Ahh, yes, you're right. HEAD...MERGE_HEAD is the more important half of what --merge gives us that I failed to mention.
And without the symmetric difference traversal it gives, --left-right would of course not work, either.
Re: [PATCH 2/7] [doc] git-merge: link to new merge conflicts guide
In reply to Julia EvansQuoted 7 lines · Julia Evans
Quoted 2 lines · D. Ben Knoble
Hi Julia,
[snip]
Quoted 23 lines
Quoted 7 lines
The second is a very useful way to get more context to help resolve conflicts! I have an alias "conflict = log --oneline --graph --left-right --boundary --merge" for a similar purpose, and I think the new guide should help folks discover --merge. Often I can get a better sense of how to resolve conflicts by comparing the original changes on each side, or I might at least know who to ask about what to do.
Thanks, I meant to flag this: the reason I deleted it was really just that I couldn't understand what
git log --merge -p <path>did from the documentation and so I removed it until I could figure it out. I thought that--mergemeant that it had something to do with merge commits, but upon further investigation it looks like that's not true, and that--mergesis related to merge commits,--mergeis something totally different which is relevant any time there's a conflictMy best guess now is that it would make sense to include this under "Tools to get more context". Maybe something like this:
Quoted 3 lines
git log --merge -p <filename>will print out all commits which
caused the merge conflict for<filename>, and the diff
of how they changed the file.
Quoted 5 lines
("which caused the merge conflict for" is a little more vague, but I'm trying to convey the intent, and hopefully folks can look at
man git logif they want to know the specifics)This does sound really useful.
That reads well enough for me! Thanks.
Re: [PATCH 2/7] [doc] git-merge: link to new merge conflicts guide
In reply to Julia EvansQuoted 20 lines · Julia Evans
Quoted 19 lines · D. Ben Knoble
Hi Julia,
Documentation/git-merge.adoc git merge v1.2.3^0 · line 243
Quoted 11 lines · Julia Evans via GitGitGadget
From: Julia Evans <[email protected]>
All of the info about merge conflicts has been moved to the new guide
Among the changes made to the common ancestor's version,
Documentation/git-merge.adoc +0
-5-non-overlapping ones (that is, you changed an area of the file while the -other side left that area intact, or vice versa) are incorporated in the -final result verbatim. When both sides made changes to the same area, -however, Git cannot randomly pick one side over the other, and asks you to -resolve it by leaving what both sides did to that area.I think these are both valuable pieces of information we have lost in the new guide (unless I misremember just having read patch 1 :).
Quoted 5 lines
Quoted 3 lines
The first explains a bit more about what a conflict *is*. Maybe that's old-hat nowadays, but I think it could be nice to keep a statement about why conflicts exist.
Will think about this!
After talking this through with my collaborator Marie, we wrote a new "what is a merge conflict?" section which I'll include in the v2.
Like I mentioned before elsewhere it takes a super light approach to introducing the 3-way merge. (there is intentionally no mention of "since they diverged from the common ancestor" etc)
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 hello.py, then it can easily combine them.
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 leaves them unstaged, puts both sides' edits in the file, and leaves <<markers, merge conflict markers>> that you need to resolve.
Re: [PATCH 2/7] [doc] git-merge: link to new merge conflicts guide
Quoted 11 lines · Julia Evans
Like I mentioned before elsewhere it takes a super light approach to introducing the 3-way merge. (there is intentionally no mention of "since they diverged from the common ancestor" etc)
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.pyand the other side edited lines 20-25 ofhello.py, then it can easily combine them.
Some immediate reactions.
- Is it obvious that the reason why it can "easily combine" them, or would it help to be more explicit (i.e., "as there is no overlap")?
- The second "of hello.py" forced me to go back and look at the first one again to make sure we are talking about the same file. I would imagine if the latter were "lines 20-25 of the same file", it would have read better at least to me.
Quoted 4 lines
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".
- "cannot guess" would be more direct than "will not try to guess".
Quoted 4 lines
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
- "merged without conflicts" would be more direct than "successfully merged".
Quoted 3 lines
* For the files with conflicts, it leaves them unstaged, puts both sides' edits in the file, and leaves <<markers, merge conflict markers>> that you need to resolve.
- "unstaged" sounds as if somebody ran "git rm --cached" on the paths, but that is not what you want to tell your readers.
- "it leaves them unstaged" -> "it remembers them as conflicted", perhaps? This hints that Git has a mechanism to remember the conflicted paths even after you removed the conflict markers from the file to your readers.
Re: [PATCH 2/7] [doc] git-merge: link to new merge conflicts guide
Quoted 9 lines
Quoted 7 lines
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.pyand the other side edited lines 20-25 ofhello.py, then it can easily combine them.Some immediate reactions.
Thanks, incorporated a few of these ("it marks them as conflicted", "since there's no overlap", "the same file")
Quoted 6 lines
Quoted 4 lines
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".
- "cannot guess" would be more direct than "will not try to guess".
The way I think about it as a user is that Git takes an intentionally conservative approach and I appreciate the conservatism. Compared to a more aggressive syntax-aware merge system like mergiraf which has done merges I don't agree with.
Re: [PATCH 2/7] [doc] git-merge: link to new merge conflicts guide
Quoted 6 lines · Julia Evans
Quoted 1 line
- "cannot guess" would be more direct than "will not try to guess".
The way I think about it as a user is that Git takes an intentionally conservative approach and I appreciate the conservatism. Compared to a more aggressive syntax-aware merge system like
mergirafwhich has done merges I don't agree with.
Your disagreement with their result suggests that they guessed when they could not do so reliably. I agree that our approach is more conservative, but we can call it being more honest.
;-).
Re: [PATCH 2/7] [doc] git-merge: link to new merge conflicts guide
In reply to Julia EvansQuoted 50 lines · Julia Evans
Quoted 20 lines · Julia Evans
Quoted 19 lines · D. Ben Knoble
Hi Julia,
Documentation/git-merge.adoc git merge v1.2.3^0 · line 243
Quoted 11 lines · Julia Evans via GitGitGadget
From: Julia Evans <[email protected]>
All of the info about merge conflicts has been moved to the new guide
Among the changes made to the common ancestor's version,
Documentation/git-merge.adoc +0
-5-non-overlapping ones (that is, you changed an area of the file while the -other side left that area intact, or vice versa) are incorporated in the -final result verbatim. When both sides made changes to the same area, -however, Git cannot randomly pick one side over the other, and asks you to -resolve it by leaving what both sides did to that area.I think these are both valuable pieces of information we have lost in the new guide (unless I misremember just having read patch 1 :).
Quoted 5 lines
Quoted 3 lines
The first explains a bit more about what a conflict *is*. Maybe that's old-hat nowadays, but I think it could be nice to keep a statement about why conflicts exist.
Will think about this!
After talking this through with my collaborator Marie, we wrote a new "what is a merge conflict?" section which I'll include in the v2.
Like I mentioned before elsewhere it takes a super light approach to introducing the 3-way merge. (there is intentionally no mention of "since they diverged from the common ancestor" etc)
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.pyand the other side edited lines 20-25 ofhello.py, then it can easily combine them.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".
Quoted 8 lines
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 leaves them unstaged, puts both sides' edits in the file, and leaves <<markers, merge conflict markers>> that you need to resolve.
I quite like this. I'm sure it oversimplifies somewhere, but at least I personally cannot immediately see where (or how it does any harm to) ;)
Thanks!
PS Unlike Junio---perhaps due to my lack of older Git history and terminology, despite using Git since 2016?---I would never have read "unstaged" as *deleted* from the index. Just changed and not updated in the index (i.e., not "git add"-ed).
Signature · 1 line
D. Ben Knoble
Re: [PATCH 2/7] [doc] git-merge: link to new merge conflicts guide
Quoted 4 lines · D. Ben Knoble
PS Unlike Junio---perhaps due to my lack of older Git history and terminology, despite using Git since 2016?---I would never have read "unstaged" as *deleted* from the index. Just changed and not updated in the index (i.e., not "git add"-ed).
I agree such an interpretation is certainly possible.
The verb "to unstage" would be the opposite of "to stage", but it is ambiguous what kind of oppositeness you want to express. This is unlike "to stage" whose possible interpretation is fairly narrow. You register the contents that you consider desirable for the path using various means. On the other hand, "to unstage" is undoing the result of your earlier act "to stage", but it may mean reverting to what is recorded in HEAD (i.e., "git reset HEAD -- path"), undoing the fact that you added a path to the index (i.e., "git rm --cached -- path"). Neither interpretation is what you want when talking about what a conflicted merge does to remember the three stages for a conflicted path in the index.
Hence my suggestion to avoid using the verb.
Re: [PATCH 2/7] [doc] git-merge: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetQuoted 3 lines · Julia Evans via GitGitGadget
From: Julia Evans <[email protected]>
All of the info about merge conflicts has been moved to the new guide
Pedantic nit: missing punctuation.
Other than that I agree with Ben, one part that we lose here is some context on what a merge conflict even is.
Patrick
PATCH 3/7 git-rebase: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
Remove some of the detail about how to handle a merge conflict, since it's explained in detail in the new guide, and there probably isn't enough detail anyway.
Leave the steps since rebase is special and has a --skip option which the other commands which cause merge conflicts don't have.
--- Documentation/git-rebase.adoc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
Documentation/git-rebase.adoc +9 -4
@@ -46,10 +46,7 @@ If there is a merge conflict during this process, `git rebase` will stop at the first problematic commit and leave conflict markers. If this happens, you can do one of these things: -1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<) - and make edits to resolve the conflict. For each file you edit, you need to - tell Git that the conflict has been resolved. You can mark the conflict as - resolved with `git add <filename>`. After resolving all of the conflicts, +1. Resolve the conflict. After resolving all of the conflicts, you can continue the rebasing process with git rebase --continue
@@ -62,6 +59,9 @@ one of these things: git rebase --skip +See linkgit:gitmergeconflicts[7] (or `git help mergeconflicts`) +for a full guide to handling merge conflicts. + If you don't specify an `<upstream>` to rebase onto, the upstream configured in `branch.<name>.remote` and `branch.<name>.merge` options will be used (see linkgit:git-config[1] for details) and the `--fork-point` option is
@@ -1284,6 +1284,11 @@ include::includes/cmd-config-section-all.adoc[] include::config/rebase.adoc[] include::config/sequencer.adoc[] +SEE ALSO +-------- + +linkgit:gitmergeconflicts[7] + GIT --- Part of the linkgit:git[1] suite
Signature · 1 line
gitgitgadget
PATCH 4/7 git-revert: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
--- Documentation/git-revert.adoc | 5 +++++ 1 file changed, 5 insertions(+)
Documentation/git-revert.adoc +5 -0
@@ -31,6 +31,10 @@ both will discard uncommitted changes in your working directory. See "Reset, restore and revert" in linkgit:git[1] for the differences between the three commands. +If there have been new commits since the reverted conflict, there may +be a merge conflict. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts. + OPTIONS ------- <commit>...::
@@ -162,6 +166,7 @@ include::config/revert.adoc[] SEE ALSO -------- linkgit:git-cherry-pick[1] +linkgit:gitmergeconflicts[7] GIT ---
Signature · 1 line
gitgitgadget
PATCH 5/7 git-cherry-pick: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
Remove the discussion of merge conflicts and replace it with a link to the guide.
--- Documentation/git-cherry-pick.adoc | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-)
Documentation/git-cherry-pick.adoc +4 -19
@@ -19,25 +19,9 @@ Given one or more existing commits, apply the change each one introduces, recording a new commit for each. This requires your working tree to be clean (no modifications from the HEAD commit). -When it is not obvious how to apply a change, the following -happens: - -1. The current branch and `HEAD` pointer stay at the last commit - successfully made. -2. The `CHERRY_PICK_HEAD` ref is set to point at the commit that - introduced the change that is difficult to apply, unless the - `--no-commit` option was given. -3. Paths in which the change applied cleanly are updated both - in the index file and in your working tree. -4. For conflicting paths, the index file records up to three - versions, as described in the "TRUE MERGE" section of - linkgit:git-merge[1]. The working tree files will include - a description of the conflict bracketed by the usual - conflict markers `<<<<<<<` and `>>>>>>>`. -5. No other modifications are made. - -See linkgit:git-merge[1] for some hints on resolving such -conflicts. +When it is not obvious how to apply a change, there may +be a merge conflict. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts. OPTIONS -------
@@ -259,6 +243,7 @@ $ git cherry-pick -Xpatience topic^ <4> SEE ALSO -------- linkgit:git-revert[1] +linkgit:gitmergeconflicts[7] GIT ---
Signature · 1 line
gitgitgadget
Re: [PATCH 5/7] [doc] git-cherry-pick: link to new merge conflicts guide
Quoted 30 lines · Julia Evans via GitGitGadget
From: Julia Evans <[email protected]>
Remove the discussion of merge conflicts and replace it with a link to the guide.
Signed-off-by Julia Evans <[email protected]>--- Documentation/git-cherry-pick.adoc | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-)Documentation/git-cherry-pick.adoc +0
-12@@ -19,25 +19,9 @@ Given one or more existing commits, apply the change each one introduces, recording a new commit for each. This requires your working tree to be clean (no modifications from the HEAD commit). -When it is not obvious how to apply a change, the following -happens: - -1. The current branch and `HEAD` pointer stay at the last commit - successfully made. -2. The `CHERRY_PICK_HEAD` ref is set to point at the commit that - introduced the change that is difficult to apply, unless the - `--no-commit` option was given. -3. Paths in which the change applied cleanly are updated both - in the index file and in your working tree. -4. For conflicting paths, the index file records up to three - versions, as described in the "TRUE MERGE" section of
Documentation/git-cherry-pick.adoc Given one or more existing commits, apply the change each one · line 24
Quoted 10 lines
Documentation/git-cherry-pick.adoc +3
-7- linkgit:git-merge[1]. The working tree files will include - a description of the conflict bracketed by the usual - conflict markers `<<<<<<<` and `>>>>>>>`. -5. No other modifications are made. - -See linkgit:git-merge[1] for some hints on resolving such -conflicts. +When it is not obvious how to apply a change, there may +be a merge conflict. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts.
The new document may explain how to resolve conflicts, but are the details removed from here that are specific to the 'cherry-pick' operation also covered there?
For example, during a difficult cherry-pick, it is often handy to be able to run 'git show CHERRY_PICK_HEAD', but now users are not told about the pseudo-ref, which seems like a real loss.
The fact that cleanly auto-resolved contents for paths are recorded in the index may be shared with all other merge-like operations, and it need not be part of the "how to resolve a conflicted merge-like operation" recipe, but users need to be assured that this is what happens somewhere in the documentation set. The list removed here served that purpose for this specific command, but it is now gone.
I do not recall offhand whether we explicitly tell our users that all merge-like operations update the index with cleanly auto-resolved results and only leave conflicts to be hand-resolved by the user, but even if we did so elsewhere, I do not see any reference to that in the existing text of the 'cherry-pick' manual, nor does this patch series add such a link. At least item #2 and #3 should be kept in the list, I think. A better alternative might be to add your new reference, and shorten the description given in item #4, and leave everything else as before.
Thanks.
Quoted 11 lines
Documentation/git-cherry-pick.adoc +1
-0OPTIONS -------@@ -259,6 +243,7 @@ $ git cherry-pick -Xpatience topic^ <4> SEE ALSO -------- linkgit:git-revert[1] +linkgit:gitmergeconflicts[7] GIT ---
Re: [PATCH 5/7] [doc] git-cherry-pick: link to new merge conflicts guide
Quoted 4 lines
The new document may explain how to resolve conflicts, but are the details removed from here that are specific to the 'cherry-pick' operation also covered there?
I'll update this series to make fewer changes to this page as you suggest to make the diff smaller.
Quoted 3 lines
For example, during a difficult cherry-pick, it is often handy to be able to run 'git show
CHERRY_PICK_HEAD', but now users are not told about the pseudo-ref, which seems like a real loss.
I'll put this back for now, but I removed it because I couldn't understand why CHERRY_PICK_HEAD might be useful, and some of my user research showed that almost nobody uses CHERRY_PICK_HEAD. I always appreciate people telling me why these things are actually useful though, and even if very few people use something, maybe more people would use it if it was clear why it's useful :)
My best guess (based on what you said) is that CHERRY_PICK_HEAD is only useful if you're cherry-picking multiple commits at the same time. Is the following an accurate explanation?:
Quoted 5 lines
If the conflict happened when cherry picking multiple commits, you can run
git show CHERRY_PICK_HEADto see the commit that Git failed to apply.
Quoted 7 lines
The fact that cleanly auto-resolved contents for paths are recorded in the index may be shared with all other merge-like operations, and it need not be part of the "how to resolve a conflicted merge-like operation" recipe, but users need to be assured that this is what happens somewhere in the documentation set. The list removed here served that purpose for this specific command, but it is now gone.
That makes sense to me. One major benefit of making a centralized page is that each man page explains different aspects of the merge conflict process, and we can make sure that anyone who needs to solve a merge conflict is aware of all the aspects. I'll think about how to explain that.
Re: [PATCH 5/7] [doc] git-cherry-pick: link to new merge conflicts guide
Quoted 6 lines · Julia Evans
My best guess (based on what you said) is that
CHERRY_PICK_HEADis only useful if you're cherry-picking multiple commits at the same time. Is the following an accurate explanation?:Quoted 2 lines
If the conflict happened when cherry picking multiple commits, you can run
git show CHERRY_PICK_HEADto see the commit that Git failed to apply.
You do not have to limit yourself to the multi-pick case. If you make it a habit to use CHERRY_PICK_HEAD, you do not have to remember exactly which commit you specified on the command line to pick when stopped by a conflict during a cherry-pick. This is especially true for those who have already made it a habit to use MERGE_HEAD when stopped by a conflict during a merge. Not having to think when you can mechanically perform a routine task is bliss.
PATCH 6/7 git-pull: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
--- Documentation/git-pull.adoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Documentation/git-pull.adoc +2 -1
@@ -38,7 +38,8 @@ or `pull.ff` with your preferred behaviour. If there's a merge conflict during the merge or rebase that you don't want to handle, you can safely abort it with `git merge --abort` or -`git rebase --abort`. +`git rebase --abort`. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts. OPTIONS -------
Signature · 1 line
gitgitgadget
PATCH 7/7 ignore conflict markers in gitmergeconflicts.adoc
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
--- .gitattributes | 1 + 1 file changed, 1 insertion(+)
.gitattributes +1 -0
@@ -14,6 +14,7 @@ CODE_OF_CONDUCT.md -whitespace /t/oid-info/* text eol=lf /Documentation/git-merge.adoc conflict-marker-size=32 /Documentation/git-merge-file.adoc conflict-marker-size=32 +/Documentation/gitmergeconflicts.adoc conflict-marker-size=32 /Documentation/gitk.adoc conflict-marker-size=32 /Documentation/user-manual.adoc conflict-marker-size=32 /t/t????-*.sh conflict-marker-size=32
Signature · 1 line
gitgitgadget
Re: [PATCH 7/7] [doc] ignore conflict markers in gitmergeconflicts.adoc
Quoted 13 lines · Julia Evans via GitGitGadget
Subject: Re: [PATCH 7/7] [doc] ignore conflict markers in gitmergeconflicts.adoc
From: Julia Evans <[email protected]>Signed-off-by Julia Evans <[email protected]>--- .gitattributes | 1 + 1 file changed, 1 insertion(+).gitattributes +0
-0
.gitattributes CODE_OF_CONDUCT.md -whitespace · line 20
Quoted 7 lines
.gitattributes +1
-0@@ -14,6 +14,7 @@ CODE_OF_CONDUCT.md -whitespace /t/oid-info/* text eol=lf /Documentation/git-merge.adoc conflict-marker-size=32 /Documentation/git-merge-file.adoc conflict-marker-size=32 +/Documentation/gitmergeconflicts.adoc conflict-marker-size=32 /Documentation/gitk.adoc conflict-marker-size=32 /Documentation/user-manual.adoc conflict-marker-size=32 /t/t????-*.sh conflict-marker-size=32
The title of this patch seems to show a fundamental misunderstanding of what these custom conflict marker settings mean. I believe the plan is to squash this into the step that introduces the new file; when that happens, the patch title will disappear and we will not have to worry about it, but regardless.
Setting a custom 'conflict-marker-size' is not about ignoring anything. It ensures that payload lines that happen to look like conflict markers are not mistaken for them. Machinery like rerere parses conflicted files, and you do not want it to mistake a run of seven '<' characters at the beginning of a line you deliberately wrote as the start of a conflict block. You prevent such mistakes by specifying that the conflict delimiter used during conflicts will be N (!= 7) characters long, instead of the regular seven.
By the way, some of the points above might be worth teaching in the material covering merge conflicts (i.e., this series). I do not think many people write manuals on Git with examples of what a conflict block looks like ;-), but a run of seven '<', '=', '|', or '>' characters may appear in real payloads that users need to use, in contexts completely unrelated to ours.
Setting 'conflict-marker-size' to a length that their payload is unlikely to use is a useful technique to be aware of.
Thanks.
Re: [PATCH 7/7] [doc] ignore conflict markers in gitmergeconflicts.adoc
Quoted 19 lines · Junio C Hamano
Quoted 17 lines · Julia Evans via GitGitGadget
Subject: Re: [PATCH 7/7] [doc] ignore conflict markers in gitmergeconflicts.adoc
From: Julia Evans <[email protected]>Signed-off-by Julia Evans <[email protected]>--- .gitattributes | 1 + 1 file changed, 1 insertion(+).gitattributes +1
-0@@ -14,6 +14,7 @@ CODE_OF_CONDUCT.md -whitespace /t/oid-info/* text eol=lf /Documentation/git-merge.adoc conflict-marker-size=32 /Documentation/git-merge-file.adoc conflict-marker-size=32 +/Documentation/gitmergeconflicts.adoc conflict-marker-size=32
Quoted 8 lines
.gitattributes CODE_OF_CONDUCT.md -whitespace · line 20
Quoted 3 lines
.gitattributes +0
-0/Documentation/gitk.adoc conflict-marker-size=32 /Documentation/user-manual.adoc conflict-marker-size=32 /t/t????-*.sh conflict-marker-size=32I believe the
plan is to squash this into the step that introduces the new file; when that happens, the patch title will disappear and we will not have to worry about it
Yes, I squashed it in the new version. I don't share your opinions about how the title of this patch was worded but it's such a minor point that I don't think it's worth discussing.
Quoted 9 lines
By the way, some of the points above might be worth teaching in the material covering merge conflicts (i.e., this series). I do not think many people write manuals on Git with examples of what a conflict block looks like ;-), but a run of seven '<', '=', '|', or '>' characters may appear in real payloads that users need to use, in contexts completely unrelated to ours.
Setting 'conflict-marker-size' to a length that their payload is unlikely to use is a useful technique to be aware of.
I do not think that would be useful to explain in this series. (since as you say Git's situation is unusual and it's not a good practice to explain things that we don't think are relevant
"just in case"). If users ask for it to be covered in the future
we can add it then.
Quoted 8 lines · Julia Evans via GitGitGadget
Julia Evans (7):
[doc] Add new gitmergeconflicts man page
[doc] git-merge: link to new merge conflicts guide [doc] git-rebase: link to new merge conflicts guide [doc] git-revert: link to new merge conflicts guide [doc] git-cherry-pick: link to new merge conflicts guide [doc] git-pull: link to new merge conflicts guide [doc] ignore conflict markers in gitmergeconflicts.adoc
With this merged, 'seen' seems to fail
$ make check-docs
with these lines at the end
...
MKDIR -p .build/lint-docs/doc-style/includes LINT DOCSTYLE includes/cmd-config-section-all.adoc LINT DOCSTYLE includes/cmd-config-section-rest.adoc GEN lint-docs-manpages
no link: gitmergeconflicts
Thanks.
Quoted 15 lines · Junio C Hamano
Quoted 8 lines · Julia Evans via GitGitGadget
Julia Evans (7):
[doc] Add new gitmergeconflicts man page
[doc] git-merge: link to new merge conflicts guide [doc] git-rebase: link to new merge conflicts guide [doc] git-revert: link to new merge conflicts guide [doc] git-cherry-pick: link to new merge conflicts guide [doc] git-pull: link to new merge conflicts guide [doc] ignore conflict markers in gitmergeconflicts.adocWith this merged, 'seen' seems to fail
$ make check-docs
Quoted 8 lines
with these lines at the end
...
MKDIR -p .build/lint-docs/doc-style/includes LINT DOCSTYLE includes/cmd-config-section-all.adoc LINT DOCSTYLE includes/cmd-config-section-rest.adoc GEN lint-docs-manpages
no link: gitmergeconflicts
Weirdly applying Julia's patches myself did not result in the same error. It's only when they're merged to seen. Ah. It's due to ta/command-list-guides-sync-lint, which isn't yet in master.
I think that is giving us a good signal, though. The guide should be mentioned in command-list.txt, so that it is linked from git(1). See c655855559 (doc: git: list gitdatamodel(7) as a concept guide, 2026-09-05) for some prior art.
-Peff
Quoted 2 lines
I think that is giving us a good signal, though. The guide should be mentioned in command-list.txt, so that it is linked from git(1).
Thanks, will fix this (and will move the conflict-marker-size change).
Should I be trying to apply my patches to seen before submitting them?
- Julia
Quoted 6 lines · Julia Evans
Quoted 2 lines
I think that is giving us a good signal, though. The guide should be mentioned in command-list.txt, so that it is linked from git(1).
Thanks, will fix this (and will move the conflict-marker-size change).
Should I be trying to apply my patches to
seenbefore submitting them?
In general, no, you don't have to. In this case it turned up useful information for changing your series, but that's rare. The more likely outcome is that there's nothing to be changed in your series, but there's a conflict (either textual or semantic) between two topics that has to be resolved by the maintainer.
Of course if you know about that conflict and can warn people in the cover letter (and sometimes even suggest a resolution, or work around it somehow), that can distribute some of the load. But I don't know that I would recommend for everyone to manually merge their topic to 'seen' in the hopes that it finds something useful. It usually won't.
But depending on the rest of your workflow, you might get advanced warning of such interactions for free-ish. For example, I merge all of my personal topics every day to the "jch" branch to build the version of Git that I run day-to-day. So I learn about those interactions early when my build fails, or my personal copy breaks. ;) But that's not something I'd expect most people to do.
If you do want to look ahead, I think "next" or "jch" is often a more useful target. A topic on the seen branch just means it was seen by the maintainer, and might not even pass all of the tests. Whereas "next" is fairly stable, and "jch" is (I believe) what Junio runs day to day (so a subset of "seen" that seems pretty stable).
-Peff
Quoted 5 lines · Jeff King
Quoted 3 lines · Julia Evans
Quoted 2 lines
I think that is giving us a good signal, though. The guide should be mentioned in command-list.txt, so that it is linked from git(1).
Quoted 8 lines
Quoted 3 lines
Thanks, will fix this (and will move the conflict-marker-size change).
Should I be trying to apply my patches to
seenbefore submitting them?In general, no, you don't have to. In this case it turned up useful
...
If you do want to look ahead, I think "next" or "jch" is often a more useful target.
As Julia is working mostly on documentation modernization, what you and I view as an advantage may not be as relevant to her as it is to those who work with code.
Regardless of which "more advanced" branch you pick to cross-check with other topics in flight, I do not think you want to apply your patches _on_ that branch. Rather, apply your patches on a stable base (e.g., a release tag, or the tip of then-current 'master'), and make a trial merge of your topic branch into the "more advanced" target branch.
Even without building, you may find merge conflicts, through which you will learn what other contributors are working on in the same area. You may run git log --merge --left-right -p right there while you have conflicts, and may even learn that a helper function or two your topic would benefit from have already been written in their topics. Even when there is no textual conflict, 'make' (just building alone) may reveal that an API function your topic depends on has been updated by another topic in flight, and the result does not even build as a consequence. Again, you learn about the topics by others that may be very relevant to you.
If you are working in a fairly isolated area, none of the above may happen, of course.
Quoted 4 lines
A topic on the seen branch just means it was seen by the maintainer, and might not even pass all of the tests. Whereas "next" is fairly stable, and "jch" is (I believe) what Junio runs day to day (so a subset of "seen" that seems pretty stable).
These days my personal rule is to make sure that the topics must be in 'jch' before it is marked with "Will merge to 'next'".
A big thank you for working on this.
Quoted 13 lines · Julia Evans via GitGitGadget
Handling merge conflicts is difficult, and currently Git's guidance on merge conflicts isn't giving users the information they need to navigate the process. As usual, the process I used to write this was to collect comments from Git users on the existing documentation, and then address those issues. I listed the specific issues we're aiming to solve in the first commit message in the series.
This patch series introduces a new manual page, gitmergeconflicts, which explains the process of explaining a merge conflict with examples. It also links to that new page from the commands which can cause merge conflicts, instead of trying to reexplain the process every time.
Quoted 5 lines
This is a pretty big change, so here's a list of things I'm still considering in the hopes that it'll help with the discussion:
* I wrote that git commit does the same thing as git merge --continue during a git merge , but I'm not sure if that's always true.
See also discussion in
https://lore.kernel.org/git/CABPp-BEQSx4m3BcT28CpVGCtsH75+x3gmv4OJz_ecLVLx+kBWg@mail.gmail.com/T/#t
Quoted 9 lines
* Right now we're listing git merge, git revert, git rebase, git cherry-pick, and git pull as commands that can cause merge conflicts. I believe that git apply and git am can also result in conflicts when applying a patch, though it's a bit complicated because applying a patch is a different operation than doing a 3-way merge and the tools available for dealing with it are a different. My thought right now is to avoid the issue of applying patches for now (because it's a whole can of worms) and instead just try to not imply that this is necessarily an exhaustive list.
I think that's a good approach!
Quoted 2 lines
Also if/when the git rebase --squash changes land, then we'd need
to add git history to this list.
I imagine you meant history squash? I also thought that history had punted on how to deal with conflicts (rejecting any operation which creates them) for now, since we don't have 1st-class conflicts à la Jujutsu.
Quoted 5 lines
* Instead of creating a new page, I considered using an include to have a "handling merge conflicts" section in git rebase, git merge, etc. Merge conflict resolution is complex and it's very useful to be able to include
examples: this version ended up at ~300 lines and I think that's too big of an include, especially for short man pages like cherry-pick
Sensible. I have often wished some of our includes were actually links to separate documents, to keep overall document size down.
Quoted 10 lines
* Explaining what "ours" and "theirs" mean was one of the hardest parts of writing this. From polling Git users in one of my many informal Mastodon polls about Git, my understanding is that Git users are actually relatively unlikely to actually reason about what "ours" and "theirs" mean when dealing with a merge conflict, and that most people prefer to get more context instead, for example by using a mergetool or by using diff3 or zdiff3. I heard a lot of "I can never remember which is which I so I don't even try". So I put the information about what "ours" and "theirs" mean relatively far down the page (with some cross-references), so that it's easily available but not the main focus.
I think the biggest reason to (ahem) reason about these is if one wants to restore --{ours,theirs} or restart and try again with a merge strategy -s {ours,theirs} [rare] or merge strategy option -X {ours,theirs} [less rare].
But, leaving it out of focus makes sense to me!
Quoted 4 lines
* I removed a couple of mentions of the various
_HEADreferences. It's hard for me to know exactly where they belong because I personally have never usedMERGE_HEAD,REBASE_HEAD,ORIG_HEAD,CHERRY_PICK_HEADetc, and I don't know how they're meant to be used.
My most frequently use is "git show REBASE_HEAD" (which is what "git rebase --show-current-patch" does, albeit with more typing). :shrug:
Signature · 1 line
D. Ben Knoble
Thanks for the review!
Quoted 5 lines
Quoted 2 lines
* I wrote that git commit does the same thing as git merge --continue during a git merge , but I'm not sure if that's always true.
See also discussion in
https://lore.kernel.org/git/CABPp-BEQSx4m3BcT28CpVGCtsH75+x3gmv4OJz_ecLVLx+kBWg@mail.gmail.com/T/#t
Wow, that's a very interesting read. I'm more informed than I was before I read it but also at the same time more confused :). It makes me think that "git commit does the same thing as git merge --continue" is maybe not true but also I don't know what the difference might be.
I've put an item on my TODO list to removegit commit does the same thing as git merge --continue" and to try to replace it with a more vague sentence that I guess says you can use either command without being so specific on whether they are exactly the same.
Quoted 7 lines
Quoted 2 lines
Also if/when the git rebase --squash changes land, then we'd need
to add git history to this list.I imagine you meant history squash? I also thought that history had punted on how to deal with conflicts (rejecting any operation which creates them) for now, since we don't have 1st-class conflicts à la Jujutsu.
Good to know! Removed this from my v2 cover letter draft.
Quoted 14 lines · Julia Evans
Thanks for the review!
Quoted 5 lines
Quoted 2 lines
* I wrote that git commit does the same thing as git merge --continue during a git merge , but I'm not sure if that's always true.
See also discussion in
https://lore.kernel.org/git/CABPp-BEQSx4m3BcT28CpVGCtsH75+x3gmv4OJz_ecLVLx+kBWg@mail.gmail.com/T/#tWow, that's a very interesting read. I'm more informed than I was before I read it but also at the same time more confused :). It makes me think that "git commit does the same thing as git merge --continue" is maybe not true but also I don't know what the difference might be.
Quoted 5 lines
I've put an item on my TODO list to remove
git commit does the same thing as git merge --continue" and to try to replace it with a more vague sentence that I guess says you can use either command without being so specific on whether they are exactly the same.
For now I would say the subtleties in that conversation really make me lean towards the following:
- "git <thing> --continue" is, for most users in most cases, the right thing to do. It's what "git status" recommends and will practically never do anything surprising (?).
- However, it may not always be exactly what you *want*---and you'll usually know when you want to go "outside" the normal sequencer and commit directly (because you'll have understood some nuanced details about what can happen).
For merge it may be the case that they're the same, I suppose (I'm genuinely not sure), but I would prefer to simplify folks' paths by recommending one of the few uniform interfaces we have :)
Quoted 21 lines · D. Ben Knoble
Quoted 14 lines · Julia Evans
Thanks for the review!
Quoted 5 lines
Quoted 2 lines
* I wrote that git commit does the same thing as git merge --continue during a git merge , but I'm not sure if that's always true.
See also discussion in
https://lore.kernel.org/git/CABPp-BEQSx4m3BcT28CpVGCtsH75+x3gmv4OJz_ecLVLx+kBWg@mail.gmail.com/T/#tWow, that's a very interesting read. I'm more informed than I was before I read it but also at the same time more confused :). It makes me think that "git commit does the same thing as git merge --continue" is maybe not true but also I don't know what the difference might be.
Quoted 5 lines
I've put an item on my TODO list to remove
git commit does the same thing as git merge --continue" and to try to replace it with a more vague sentence that I guess says you can use either command without being so specific on whether they are exactly the same.
Quoted 6 lines
For now I would say the subtleties in that conversation really make me lean towards the following:
- "git <thing> --continue" is, for most users in most cases, the right thing to do. It's what "git status" recommends and will practically never do anything surprising (?).
I was actually surprised to discover that git status does not recommend git merge --continue: it recommends git commit.
Maybe we should change that though?
I agree it makes sense to be consistent with what git status recommends.
Quoted 8 lines
- However, it may not always be exactly what you *want*---and you'll usually know when you want to go "outside" the normal sequencer and commit directly (because you'll have understood some nuanced details about what can happen).
For merge it may be the case that they're the same, I suppose (I'm genuinely not sure), but I would prefer to simplify folks' paths by recommending one of the few uniform interfaces we have :)
The only other thing that gives me pause about recommending folks git merge --continue too strongly is that as we know Git users are slow to change their habits, and we don't want to confuse anyone. If someone is currently using git commit I want to know that they can keep doing it the same way with no worries.
Maybe if we change git status to recommend git merge --continue, and we think there are no real advantages to using git commit instead of git merge --continue, then we could say something like this:
NOTE: git commit is an older alternative to git merge --continue. You can use either one after resolving a git merge.
Quoted 10 lines · Julia Evans
Quoted 7 lines
For now I would say the subtleties in that conversation really make me lean towards the following:
- "git <thing> --continue" is, for most users in most cases, the right thing to do. It's what "git status" recommends and will practically never do anything surprising (?).
I was actually surprised to discover that
git statusdoes not recommendgit merge --continue: it recommendsgit commit.
Wow, yeah! I'm surprised, too. (See wt-status.c:show_merge_in_progress(), and compare with other related functions.)
Quoted 1 line
Maybe we should change that though?
I think so, at least.
Quoted 1 line
I agree it makes sense to be consistent with what
git statusrecommends.
For sure.
Quoted 15 lines
Quoted 8 lines
- However, it may not always be exactly what you *want*---and you'll usually know when you want to go "outside" the normal sequencer and commit directly (because you'll have understood some nuanced details about what can happen).
For merge it may be the case that they're the same, I suppose (I'm genuinely not sure), but I would prefer to simplify folks' paths by recommending one of the few uniform interfaces we have :)
The only other thing that gives me pause about recommending folks
git merge --continuetoo strongly is that as we know Git users are slow to change their habits, and we don't want to confuse anyone. If someone is currently usinggit commitI want to know that they can keep doing it the same way with no worries.
Quoted 6 lines
Maybe if we change
git statusto recommendgit merge --continue, and we think there are no real advantages to usinggit commitinstead ofgit merge --continue, then we could say something like this:NOTE:
git commitis an older alternative togit merge --continue. You can use either one after resolving agit merge.
That sounds like a reasonable plan. Another plan that occurs to me is to go forward with the "commit" version (for merges; other commands should use the sequencer versions that status recommends) and update this doc later if we do change status to recommend "merge --continue".
I'd love to hear from others on either changing status output to recommend "merge --continue" or admitting that, for merges, "commit" is the same thing.
Signature · 1 line
D. Ben Knoble
Quoted 4 lines · D. Ben Knoble
I'd love to hear from others on either changing status output to recommend "merge --continue" or admitting that, for merges, "commit" is the same thing.
I see now there's a patch in-flight (downside of reading mail oldest to newest). I'll expect to discuss this particular point there, thanks!
Signature · 1 line
D. Ben Knoble
v2 cover Add new page on merge conflicts
In reply to Julia Evans via GitGitGadgetHandling merge conflicts is difficult, and currently Git's guidance on merge conflicts isn't giving users the information they need to navigate the process. As usual, the process I used to write this was to collect comments from Git users on the existing documentation, and then address those issues. I listed the specific issues we're aiming to solve in the first commit message in the series.
This patch series introduces a new manual page, gitmergeconflicts, which explains the process of explaining a merge conflict with examples. It also links to that new page from the commands which can cause merge conflicts, instead of trying to reexplain the process every time.
Changed in v2:
* [x] Explain what a merge conflict is (thanks to Junio & Ben)
* [x] rewrite the "ours" vs "theirs" section (thanks to Patrick for the comments)
* [x] add git log --merge (thanks to Ben)
* [x] Leave most of the content of git cherry-pick as-is, to make this patch set smaller (thanks to Junio)
* [x] remove the SYNOPSIS since hopefully that won't be required anymore by the time this is merged
* [x] Fix a typo in git revert (s/reverted conflict/reverted commit/)
* [x] 's/the the/the/' (thanks to Patrick)
* [x] s/[doc] Thing/doc: thing/ in commit messages (thanks to Tuomas)'
* [x] squash the commit fixing the linter error (thanks to Junio)
* [x] list reviewers in Reviewed-by
Some things that we discussed but stayed the same:
* "git commit does the same thing as git merge --continue" seems to be true so we can leave it
* Don't involve git am and git apply in this.
* Junio suggested another diff3 example but I feel like there are already a lot of examples
* We've still removed one mention of MERGE_HEAD in the git merge man page without replacing it. It's mentioned in other places though.
Thanks to Lobo, Adam Svahn, Louis Vanier, David Turner, Ben Zanin, Salih, and about 12 others who gave feedback on both the original git merge man page, as well as the proposed improvements.
Julia Evans (6):
doc: add new gitmergeconflicts man page
doc: git-merge: link to new merge conflicts guide
doc: git-rebase: link to new merge conflicts guide
doc: git-revert: link to new merge conflicts guide
doc: git-cherry-pick: link to new merge conflicts guide
doc: git-pull: link to new merge conflicts guide
.gitattributes | 1 + Documentation/Makefile | 1 + Documentation/git-cherry-pick.adoc | 11 +- Documentation/git-merge.adoc | 125 +--------- Documentation/git-pull.adoc | 3 +- Documentation/git-rebase.adoc | 13 +- Documentation/git-revert.adoc | 5 + Documentation/gitmergeconflicts.adoc | 333 +++++++++++++++++++++++++++ Documentation/meson.build | 1 + command-list.txt | 1 + 10 files changed, 362 insertions(+), 132 deletions(-) create mode 100644 Documentation/gitmergeconflicts.adoc
base-commit: 3bc0341126508f78f5869cbfc0005e987efdf0c7
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2237%2Fjvns%2Fmerge-conflicts-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2237/jvns/merge-conflicts-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/2237
Range-diff vs v1:
1: ad4853dc36 ! 1: ab0344f947 [doc] Add new gitmergeconflicts man page
@@ Metadata
Author: Julia Evans <[email protected]>
## Commit message ##
- [doc] Add new gitmergeconflicts man page
+ doc: add new gitmergeconflicts man page
Introduce a new page, gitmergeconflicts, that explains the process of handling a merge conflict in a way that addresses the following issues,
@@ Commit message
interface between similar commands.
+ Reviewed-by: D. Ben Knoble <[email protected]>
+ Reviewed-by: Patrick Steinhardt <[email protected]>
+ ## .gitattributes ##
+@@ .gitattributes: CODE_OF_CONDUCT.md -whitespace
+ /t/oid-info/* text eol=lf
+ /Documentation/git-merge.adoc conflict-marker-size=32
+ /Documentation/git-merge-file.adoc conflict-marker-size=32 ++/Documentation/gitmergeconflicts.adoc conflict-marker-size=32
+ /Documentation/gitk.adoc conflict-marker-size=32
+ /Documentation/user-manual.adoc conflict-marker-size=32
+ /t/t????-*.sh conflict-marker-size=32
+
## Documentation/Makefile ##
@@ Documentation/Makefile: MAN7_TXT += gitdiffcore.adoc
MAN7_TXT += giteveryday.adoc
@@ Documentation/gitmergeconflicts.adoc (new)
+----
+gitmergeconflicts - Guide to handling merge conflicts
+
-+
-+SYNOPSIS
-+--------
-+Guide to handling merge conflicts
-+
-+
+DESCRIPTION
+-----------
+
@@ Documentation/gitmergeconflicts.adoc (new)
+ or git rebase --abort. See <<git_status,EXAMPLE: GIT STATUS OUTPUT>> below
+ for how to find the command to run.
+
++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.
+
+[[markers]]
+MERGE CONFLICT MARKERS
+----------------------
+
-+Merge conflicts happen when both of the sides being merged edit the same -+area of a file. When this happens, Git will update the conflicted file ++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:
@@ Documentation/gitmergeconflicts.adoc (new)
+ below for how to find the command to run.
++
+Note: During a git merge, git commit and git merge --continue do
-+the the same thing.
++the same thing.
+
+
+[[example]]
@@ Documentation/gitmergeconflicts.adoc (new)
+* You can set the configuration option merge.conflictstyle=diff3.
+ See <<diff3,DIFF3 AND ZDIFF3>> 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"
@@ Documentation/gitmergeconflicts.adoc (new)
+"OURS" AND "THEIRS"
+-------------------
+
-+Git refers to the first part of a merge conflict (between <<<<<<< -+and =======) as "ours" and the second part (between ======= and -+>>>>>>>) as "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.
+
-+Normally, "ours" is the commit that was checked out before you started -+the merge, and "theirs" is the other commit.
++"Ours" and "theirs" are both commits: "ours" is the current ++HEAD commit, and "theirs" is the other side being merged.
+
-+But when the merge conflict was caused by a git rebase, it's the -+opposite: "theirs" is the commit that was checked out before you started -+the merge. This is because under the hood, git rebase main checks out -+the main commit first before doing the merge operation.
++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", "base", and "stage 1"
-+* "ours", "us", "stage 2", and HEAD
-+* "theirs", "them", and "stage 3"
++* "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
++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 the way we did in the -+<<example,example above>>, the diff would look like this:
++For example, if we resolved the conflict by adding both "banana" and ++"cherry" in order, the diff would look like this:
+
+----
+ FRUITS = [
@@ Documentation/gitmergeconflicts.adoc (new)
++ "cherry",
+ "mango",
+ "orange",
-+]
++ ]
+----
+
+[NOTE]
@@ Documentation/meson.build: manpages = {
'gitnamespaces.adoc' : 7,
'gitremote-helpers.adoc' : 7,
'gitrevisions.adoc' : 7,
+
+ ## command-list.txt ##
+@@ command-list.txt: githooks userinterfaces
+ gitignore userinterfaces
+ gitk mainporcelain
+ gitmailmap userinterfaces
++gitmergeconflicts guide
+ gitmodules userinterfaces
+ gitnamespaces guide
+ gitprotocol-capabilities developerinterfaces
2: a1686a2d82 ! 2: d5241eb901 [doc] git-merge: link to new merge conflicts guide
@@ Metadata
Author: Julia Evans <[email protected]>
## Commit message ##
- [doc] git-merge: link to new merge conflicts guide
+ doc: git-merge: link to new merge conflicts guide
All of the info about merge conflicts has been moved to the new guide
3: 128d69e482 ! 3: 72b1207045 [doc] git-rebase: link to new merge conflicts guide
@@ Metadata
Author: Julia Evans <[email protected]>
## Commit message ##
- [doc] git-rebase: link to new merge conflicts guide
+ doc: git-rebase: link to new merge conflicts guide
Remove some of the detail about how to handle a merge conflict, since it's explained in detail in the new guide, and there probably isn't
4: ab459231e0 ! 4: cfa0a8254a [doc] git-revert: link to new merge conflicts guide
@@ Metadata
Author: Julia Evans <[email protected]>
## Commit message ##
- [doc] git-revert: link to new merge conflicts guide
+ doc: git-revert: link to new merge conflicts guide
@@ Documentation/git-revert.adoc: both will discard uncommitted changes in your wor
See "Reset, restore and revert" in linkgit:git[1] for the differences between the three commands.
-+If there have been new commits since the reverted conflict, there may ++If there have been new commits since the reverted commit, there may
+be a merge conflict. See linkgit:gitmergeconflicts[7]
+(or git help mergeconflicts) for a guide to handling merge conflicts. +
5: 03a6b43b58 ! 5: 62b70e9a02 [doc] git-cherry-pick: link to new merge conflicts guide
@@ Metadata
Author: Julia Evans <[email protected]>
## Commit message ##
- [doc] git-cherry-pick: link to new merge conflicts guide
+ doc: git-cherry-pick: link to new merge conflicts guide
Remove the discussion of merge conflicts and replace it with a link to the guide.
@@ Documentation/git-cherry-pick.adoc: Given one or more existing commits, apply th
-When it is not obvious how to apply a change, the following -happens:
--
--1. The current branch and HEAD pointer stay at the last commit
-- successfully made.
--2. The CHERRY_PICK_HEAD ref is set to point at the commit that
-- introduced the change that is difficult to apply, unless the
-- --no-commit option was given.
--3. Paths in which the change applied cleanly are updated both
-- in the index file and in your working tree.
--4. For conflicting paths, the index file records up to three
-- versions, as described in the "TRUE MERGE" section of
-- linkgit:git-merge[1]. The working tree files will include
-- a description of the conflict bracketed by the usual
-- conflict markers <<<<<<< and >>>>>>>.
--5. No other modifications are made.
--
--See linkgit:git-merge[1] for some hints on resolving such --conflicts.
+When it is not obvious how to apply a change, there may +be a merge conflict. See linkgit:gitmergeconflicts[7]
+(or git help mergeconflicts) for a guide to handling merge conflicts.
++
++When a merge conflict happens:
+ 1. The current branch and HEAD pointer stay at the last commit
+ successfully made.
+@@ Documentation/git-cherry-pick.adoc: happens:
+ conflict markers <<<<<<< and >>>>>>>.
+ 5. No other modifications are made.
+
+-See linkgit:git-merge[1] for some hints on resolving such +-conflicts.
+-
OPTIONS
-------
+ <commit>...::
@@ Documentation/git-cherry-pick.adoc: $ git cherry-pick -Xpatience topic^ <4>
SEE ALSO
--------
6: d3904f0ca7 ! 6: ac77db6762 [doc] git-pull: link to new merge conflicts guide
@@ Metadata
Author: Julia Evans <[email protected]>
## Commit message ##
- [doc] git-pull: link to new merge conflicts guide
+ doc: git-pull: link to new merge conflicts guide
7: 4505fdc9a6 < -: ---------- [doc] ignore conflict markers in gitmergeconflicts.adoc
Signature · 1 line
gitgitgadget
PATCH v2 1/6 doc: add new gitmergeconflicts man page
From: Julia Evans <[email protected]>
Introduce a new page, gitmergeconflicts, that explains the process of handling a merge conflict in a way that addresses the following issues, which came from feedback from Git users on the current explanation of merge conflicts in the git merge man page:
- The process for resolving a merge conflict is only explained in the git merge man page, even though there are several other commands which can result in conflicts
- Sometimes we use "ours" and "theirs" to refer to the two sides of the merge conflicts and sometimes we use HEAD and MERGE_HEAD. It should be consistent. Also the terms "ours" and "theirs" are not explained. Similarly, it says "The part before the ======= is typically your side...", but doesn't explain what "typically" means.
- It introduces the merge format using an analogy to RCS, which very few Git users have ever used
- In "The only clean-ups you need are to reset the index file to the HEAD commit to reverse 2. and to clean up working tree changes made by 2. and 3.", it's not clear to users what "2" and "3" are supposed to mean
- It uses a cultural reference ("Conflict resolution is hard; let's go shopping.") which is confusing or unfamiliar to some people. I think it would be clearer for users to use a code example instead.
- It doesn't explain the difference between diff3 and zdiff3
- It sometimes uses the term "area" and sometimes uses the term "hunk"
Also document the unified --abort, --continue workflow in one place, since it's a really nice example of a place Git has a consistent interface between similar commands.
--- .gitattributes | 1 + Documentation/Makefile | 1 + Documentation/gitmergeconflicts.adoc | 333 +++++++++++++++++++++++++++ Documentation/meson.build | 1 + command-list.txt | 1 + 5 files changed, 337 insertions(+) create mode 100644 Documentation/gitmergeconflicts.adoc
.gitattributes +1 -0
@@ -14,6 +14,7 @@ CODE_OF_CONDUCT.md -whitespace /t/oid-info/* text eol=lf /Documentation/git-merge.adoc conflict-marker-size=32 /Documentation/git-merge-file.adoc conflict-marker-size=32 +/Documentation/gitmergeconflicts.adoc conflict-marker-size=32 /Documentation/gitk.adoc conflict-marker-size=32 /Documentation/user-manual.adoc conflict-marker-size=32 /t/t????-*.sh conflict-marker-size=32
Documentation/Makefile +1 -0
@@ -58,6 +58,7 @@ MAN7_TXT += gitdiffcore.adoc MAN7_TXT += giteveryday.adoc MAN7_TXT += gitfaq.adoc MAN7_TXT += gitglossary.adoc +MAN7_TXT += gitmergeconflicts.adoc MAN7_TXT += gitpacking.adoc MAN7_TXT += gitnamespaces.adoc MAN7_TXT += gitremote-helpers.adoc
Documentation/gitmergeconflicts.adoc new file +333 -0
333 lines not on this page · raw message
Documentation/meson.build +1 -0
@@ -202,6 +202,7 @@ manpages = { 'gitfaq.adoc' : 7, 'gitglossary.adoc' : 7, 'gitpacking.adoc' : 7, + 'gitmergeconflicts.adoc' : 7, 'gitnamespaces.adoc' : 7, 'gitremote-helpers.adoc' : 7, 'gitrevisions.adoc' : 7,
command-list.txt +1 -0
@@ -232,6 +232,7 @@ githooks userinterfaces gitignore userinterfaces gitk mainporcelain gitmailmap userinterfaces +gitmergeconflicts guide gitmodules userinterfaces gitnamespaces guide gitprotocol-capabilities developerinterfaces
Signature · 1 line
gitgitgadget
Re: [PATCH v2 1/6] doc: add new gitmergeconflicts man page
Quoted 6 lines · Julia Evans via GitGitGadget
From: Julia Evans <[email protected]>
Introduce a new page,
gitmergeconflicts, that explains the process of handling a merge conflict in a way that addresses the following issues, which came from feedback from Git users on the current explanation of merge conflicts in thegit mergeman page:
Good goal.
Quoted 11 lines
- The process for resolving a merge conflict is only explained in the
git mergeman page, even though there are several other commands which can result in conflicts
- Sometimes we use "ours" and "theirs" to refer to the two sides of the merge conflicts and sometimes we use HEAD andMERGE_HEAD. It should be consistent. Also the terms "ours" and "theirs" are not explained. Similarly, it says "The part before the=======is typically your side...", but doesn't explain what "typically" means.
- It introduces the merge format using an analogy to RCS, which very few Git users have ever used
- In "The only clean-ups you need are to reset the index file to the
Quoted 8 lines
HEADcommit to reverse 2. and to clean up working tree changes made by 2. and 3.", it's not clear to users what "2" and "3" are supposed to mean
- It uses a cultural reference ("Conflict resolution is hard; let's go shopping.") which is confusing or unfamiliar to some people. I think it would be clearer for users to use a code example instead.
- It doesn't explain the difference between diff3 and zdiff3
- It sometimes uses the term "area" and sometimes uses the term "hunk"
It is a bit hard to evaluate this list, as we do not see any of the above problems excised from the existing documents in this step. But at least we can verify that the new text presented in this patch does not fall into the same trap as above, so I'll keep that in mind while reviewing this step.
Quoted 3 lines
Also document the unified
--abort,--continueworkflow in one place, since it's a really nice example of a place Git has a consistent interface between similar commands.
Great.
Quoted 4 lines
Co-Authored-By Marie Claire LeBlanc Flanagan <[email protected]>Reviewed-by D. Ben Knoble <[email protected]>Reviewed-by Patrick Steinhardt <[email protected]>Signed-off-by Julia Evans <[email protected]>
We want a sign-off by the coauthor, too.
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +4
-0@@ -0,0 +1,333 @@ +gitmergeconflicts(7) +==================== + +NAME
Documentation/gitmergeconflicts.adoc line 14
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+---- +gitmergeconflicts - Guide to handling merge conflicts + +DESCRIPTION +----------- + +Merge conflicts can happen during a `git merge`, `git rebase`, `git +cherry-pick`, `git pull`, or `git revert`. All of those commands use +the same merge algorithm, and the process for resolving a merge conflict +is always very similar.
Is it deliberate to omit 'am -3' and 'checkout -m', perhaps in order tolimit ourselves to most common ways to help new people by keeping the description to the absolute minimum?
Or were they just overlooked?
In any case, the first paragraph clearly stating that conflicts happen with operations other than 'merge' is a very welcome change. On this list, we often say "mergy operations can cause conflicts", with the understanding that readers know what mergy operations are and "conflicts" alone can convey the state you call "merge conflicts" in this document. But in a document for end-users, using a longer term "merge conflicts" instead of "conflicts" and avoiding "mergy operations" like you did above may be a better direction to go.
Documentation/gitmergeconflicts.adoc line 16
Quoted 1 line
Documentation/gitmergeconflicts.adoc new file +1
-0+The most common ways to handle a merge conflict are:
A natural paraphrase of the above is "A merge conflict is typically handled by these ways", but I thought the current readers are puzzled by "typically your side" that does not say when is typical.
Documentation/gitmergeconflicts.adoc line 23
Quoted 6 lines
Documentation/gitmergeconflicts.adoc new file +6
-0+* Resolve the conflict. (see <<resolve,HOW TO RESOLVE A MERGE CONFLICT>> + below for details) +* Or 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.
Both are good options and I do not think of a middle way. Perhaps we do not have to say that these are "the most common" and instead say "You handle a merge conflict by doing either of these two"?
Saying "return your branch to" is a bit misleading for two reasons. Conflicts presented to the users are primarily visible in their working tree files and the index. A single commit operations like 'merge', 'pull', and 'revert' does not touch your branch if they hit a conflict, and 'rebase' works on a detached HEAD, and stops without touching your branch when it sees a conflict.
If I were writing this, with the goal of avoiding the issues the current text has you listed in the proposed log message, I would probably say something like this:
* Or give up and return to the original state with ...
Documentation/gitmergeconflicts.adoc line 31
Quoted 7 lines
Documentation/gitmergeconflicts.adoc new file +7
-0+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.
Many of the operations, even "git merge", is not about merging "two commits" together, but I do not think of a good way to explain it, so I accept that phrasing as a helpful white lie. I mention this because somebody else may be able to come up with a better phrasing that I (or authors of this iteration) couldn't think of.
Documentation/gitmergeconflicts.adoc line 44
Quoted 12 lines
Documentation/gitmergeconflicts.adoc new file +12
-0+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.
By the way, I think we should briefly mention what sematnic merge conflicts are, and that Git does not detect them and that this manual page does not tell readers how to deal with them.
Note that non-overlapping changes from two sides may leave the result in an inconsistent state. With the edit to lines 1-5, one side may have changed the name of a function, while with the edit to lines 20-25, the other side may have added a new call to the function by its original name. This type of inconsistencies are called semantic conflicts, Git has no way knowing that a merge introduced semantic conflicts, and ends up producing a broken result without merge conflicts. This document does not cover what to do with semantic conflicts.
That is overly long, but perhaps you can condense it down to the essense and shrink down to 1/3 of the size.
Documentation/gitmergeconflicts.adoc line 51
Quoted 6 lines
Documentation/gitmergeconflicts.adoc new file +6
-0+[[markers]] +MERGE CONFLICT MARKERS +---------------------- + +When there's a merge conflict, Git will update the conflicted file +to include merge conflict markers `<<<<<<<`, `=======`, and `>>>>>>>`.
I notice that when you introduce diff3 below, you silently add ||||||| to the mix without explaining what it is.
`|||||||` may also be used as merge conflict markers (explained
later).or something along the line here may help. Or explain what it is in diff3 section. Either would work. Adding without explanation would not.
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+For example, here's a merge conflict where both sides edited a list of +fruits in different ways: + +---- +FRUITS = [ + "apple", +<<<<<<< HEAD + "cherry", +======= + "banana",
Documentation/gitmergeconflicts.adoc line 71
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+>>>>>>> add-fruit + "mango", + "orange", +] +---- + +The code from one side of the merge conflict is between `<<<<<<<` and +`=======`, and the code for the other side is between `=======` and +`>>>>>>>`. See <<ours,"OURS" AND "THEIRS">> below for a full explanation +of which side is which.
If we said "one side wanted to have 'apple, cherry, mango, orange', while the other side wanted 'apply, banana, mango, orange', in the FRUITS array", would it help the understanding? Or is it too obvious?
Quoted 29 lines
Documentation/gitmergeconflicts.adoc new file +29
-0+[[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",
Documentation/gitmergeconflicts.adoc line 112
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+<<<<<<< HEAD + "cherry", + "mango", +======= + "banana", + "mango", +>>>>>>> add-fruit + "orange", +] +----
It would make your readers puzzled why the example is subtly different from the earlier one that showed "mango" as not touched by either side. I see this lays the groundwork for later demonstration of diff3, so having both sides explicitly want "mango" is a good example. Perhaps update the first example to be the same as this one, which would reduce the mental burden by readers?
Documentation/gitmergeconflicts.adoc line 125
Quoted 13 lines
Documentation/gitmergeconflicts.adoc new file +13
-0+ +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", +] +----
OK.
Quoted 4 lines
Documentation/gitmergeconflicts.adoc new file +4
-0+[[tools]] +TOOLS FOR HANDLING MERGE CONFLICTS +---------------------------------- +
Documentation/gitmergeconflicts.adoc line 141
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+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 option `merge.conflictstyle=diff3`. + See <<diff3,DIFF3 AND ZDIFF3>> below for more.
These are called 'configuration variables' throughout the manual pages. Be consistent and replace "configuration option" with "configuration variable", perhaps?
Documentation/gitmergeconflicts.adoc line 145
Quoted 3 lines
Documentation/gitmergeconflicts.adoc new file +3
-0+* `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.
Maybe worth mentioning that --left-right often helps when you are not super familiar with the histories being merged.
Documentation/gitmergeconflicts.adoc line 150
Quoted 4 lines
Documentation/gitmergeconflicts.adoc new file +4
-0+* 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.
Maybe it will help to say we will explain "ours" and "theirs" later in this document.
Documentation/gitmergeconflicts.adoc line 158
Quoted 7 lines
Documentation/gitmergeconflicts.adoc new file +7
-0+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.
Good. This also complains about whitespace errors, by the way, but the last sentence here would be sufficient to help the readers to tell them apart.
Documentation/gitmergeconflicts.adoc line 161
Quoted 2 lines
Documentation/gitmergeconflicts.adoc new file +2
-0+* Use `git diff AUTO_MERGE` to show what changes you've made so far to + resolve the conflicts.
Does a "See below" here help readers who haven't learned what AUTO_MERGE is? If you can describe what AUTO_MERGE records (in other words, what you are comparing your progress against) in a sentence of two here, that would alleviate the need to assure them that we have more in-depth coverage on this topic elsewhere.
Quoted 4 lines
Documentation/gitmergeconflicts.adoc new file +4
-0+[[git_status]] +EXAMPLE: GIT STATUS OUTPUT +-------------------------- +
Documentation/gitmergeconflicts.adoc line 176
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+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 +* there's one file left with conflicts in it: `fruits.py`
There may be users, after seeing the last point, left puzzled why fruits.py is still listed after they edited the file like instructed in an earlier example but haven't marked the resolution.
fruits.py is not marked as its conflicts resolved yet.
or something?
Documentation/gitmergeconflicts.adoc line 189
Quoted 12 lines
Documentation/gitmergeconflicts.adoc new file +12
-0+---- +$ 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 +----
The approach to give explanations first and then an example the explanation explains next is refreshing to me. As long as the explanations are short enough, this may work better than the usual order to say "you'd see something like this. let us explain ...".
Documentation/gitmergeconflicts.adoc line 200
Quoted 9 lines
Documentation/gitmergeconflicts.adoc new file +9
-0+[[diff3]] +DIFF3 AND ZDIFF3 +---------------- + +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` or `zdiff3`. +This extra context can make it much easier to understand what's +happening in a merge conflict.
I think most on the list considers zdiff3 a failed experiment that reduces usefulness of diff3. Do we want to recommend it?
Is it obvious to readers what "original" we are talking about? We are not talking about the state we started the mergy operation from. We are talking about what the common ancestor had before two sides started working on the text to cause the divergence that conflicted.
One way I can think of to resolve this is to back to "What is a merge conflict?" section and introduce "original" right there. I'll SHOUT my additions below:
When Git merges two commits together, it looks at the changes that each side has made SINCE THE TWO SIDES DIVERGED and combines those changes. WE OFTEN CALL THIS STATE THEY DIVERGED FROM THE "ORIGINAL". 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.
If you later use "common" or "common ancestor", you can explain they are "original" we defined in the above paragraph.
Or ...
Documentation/gitmergeconflicts.adoc line 206
Quoted 5 lines
Documentation/gitmergeconflicts.adoc new file +5
-0+Here's an example of what a merge conflict would look like when using +`diff3`. It shows, in order, the "ours" side of the conflict, the +original code (`"mangoooo"`), and the "theirs" side of the +conflict. With this view, you can see that both sides fixed the spelling +mistake in "mango", and each added one fruit to the list.
... perhaps you avoid "common ancestor" altogether, with the intention to deprecate it, and introduce "original", like in the above paragraph? That is fine too. Once we establish what to call "common, ours, theirs", we should add them to glossary-contents, as I do not think we describe any of the ones we currently use there.
As I already mentioned, just like you said <<< === encloses your side and === >>> encloses their side in 2-way conflict display, we need to say <<< ||| encloses yours and ||| === encloses common in diff3 output. How theirs is shown remains the same. Here is my attempt to do so with least disruption to the flow of the text.
Here is an example of what the same conflict might look with diff3. It uses a new separator ||||||| before =======, and shows, in order the "ours" side ...
Quoted 11 lines
Documentation/gitmergeconflicts.adoc new file +11
-0+---- +FRUITS = [ + "apple", +<<<<<<< HEAD + "cherry", + "mango", +||||||| 1c22e48 + "mangoooo", +======= + "banana", + "mango",
Documentation/gitmergeconflicts.adoc line 228
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+>>>>>>> add-fruit + "orange", +] +---- + +Here's the same example using `zdiff3`. `zdiff3` takes lines that are +shared between both sides (the `"mango"` line) and moves them outside +the conflicted area. This makes the conflicted area shorter, but the +downside is that it's impossible to tell if `"mango"` was part of the +original list of fruits or not.
Yes, exactly. That is why I think we shouldn't promote it, but write it off as a failed experiment, and just tell them not to use it in this document, without giving an example.
If the original were "apple, banana, cherry, mangoooo, orange", and ours and theirs were the same as the above example, then a desirable conflict resolution would be "apple, mango, orange", because both sides knew the original had banana and cherry, and each side rejected one of them each. It would be a good demonstration of why diff3 is a better format than (rcs)merge, so if we were to spend lines on an example, I'd rather see it here, instead of zdiff3 example.
By the way, is it just me who finds those "Here's", "there's" contractions disturbing in an official manual? I've seen many of them while reviewing this to be annoyed enough and had to blurt it out X-<.
Documentation/gitmergeconflicts.adoc line 252
Quoted 7 lines
Documentation/gitmergeconflicts.adoc new file +7
-0+[[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`.
OK.
Documentation/gitmergeconflicts.adoc line 255
Quoted 2 lines
Documentation/gitmergeconflicts.adoc new file +2
-0+"Ours" and "theirs" are both commits: "ours" is the current +`HEAD` commit, and "theirs" is the other side being merged.
Now, "commits" is again a white lie. The story becomes more complicated when we talk about cherry-pick and revert, but if we primarily stick to what happens in 'merge' (which is what I've seen so far in this document), then it shouldn't add any extra difficulty to understand by saying "ours and theirs are history of changes leading to the two commits since they diverged from the original" to add clarity.
Quoted 31 lines
Documentation/gitmergeconflicts.adoc new file +31
-0+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.
Documentation/gitmergeconflicts.adoc line 297
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+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.
The first sentence gave me "Huh? You haven't explained what AUTO_MERGE is yet". It may be just me, but I would have expected presentation order to be more like:
When merge conflicts happen, the result of merge algorithm, together with conflict markers, is recorded in AUTO_MERGE. As you resolve conflicts, you can compare your working tree files against it with git diff AUTO_MERGE to see your progress.
Quoted 6 lines
Documentation/gitmergeconflicts.adoc new file +6
-0+For example, if we resolved the conflict by adding both "banana" and +"cherry" in order, the diff would look like this: + +---- + FRUITS = [ + "apple",
Documentation/gitmergeconflicts.adoc line 314
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+-<<<<<<< HEAD +- "cherry", +-======= + "banana", +->>>>>>> add-fruit ++ "cherry", + "mango", + "orange", + ] +----
Thanks.
I was puzzled by this
Quoted 4 lines
- In "The only clean-ups you need are to reset the index file to the
HEADcommit to reverse 2. and to clean up working tree changes made by 2. and 3.", it's not clear to users what "2" and "3" are supposed to mean
and did some digging.
The text comes from ffb1a4bed5 (Documentation: Describe merge operation a bit better., 2005-11-28) that had "When there are conflicts, these things happen. 1. HEAD does not move, 2. Cleanly merged paths are updated in the index 3. Conflicts are recorded in higher stage index entries and working tree files show conflict markers, 4. No other changes are done" well before the mysterious reference to 2. and 3.
When ebef7e5049 (Documentation: simplify How Merge Works, 2010-01-23) tried to simplify the description, the list of "these things happen" were removed/rewritten, and yet instructions on how to reset are left behind, still referring to 2. and 3.
We probably want a separate patch for Documentation/git-merge.adoc to rectify this 16 year old mistake.
Re: [PATCH v2 1/6] doc: add new gitmergeconflicts man page
Thanks for the review, I'm especially excited about the idea to remove zdiff3.
Quoted 6 lines
Quoted 4 lines
Co-Authored-By Marie Claire LeBlanc Flanagan <[email protected]>Reviewed-by D. Ben Knoble <[email protected]>Reviewed-by Patrick Steinhardt <[email protected]>Signed-off-by Julia Evans <[email protected]>We want a sign-off by the coauthor, too.
Will do.
Quoted 16 lines
Quoted 16 lines
Documentation/gitmergeconflicts.adoc new file +10
-0@@ -0,0 +1,333 @@ +gitmergeconflicts(7) +==================== + +NAME +---- +gitmergeconflicts - Guide to handling merge conflicts + +DESCRIPTION +----------- +
Quoted 8 lines
Documentation/gitmergeconflicts.adoc line 14
Quoted 4 lines
Documentation/gitmergeconflicts.adoc new file +4
-0+Merge conflicts can happen during a `git merge`, `git rebase`, `git +cherry-pick`, `git pull`, or `git revert`. All of those commands use +the same merge algorithm, and the process for resolving a merge conflict +is always very similar.Is it deliberate to omit 'am -3' and 'checkout -m', perhaps in order to limit ourselves to most common ways to help new people by keeping the description to the absolute minimum?
It's deliberate, we talked about that a bit in the discussion of the v1. Can add a note in the commit message.
Quoted 16 lines
In any case, the first paragraph clearly stating that conflicts happen with operations other than 'merge' is a very welcome change. On this list, we often say "mergy operations can cause conflicts", with the understanding that readers know what mergy operations are and "conflicts" alone can convey the state you call "merge conflicts" in this document. But in a document for end-users, using a longer term "merge conflicts" instead of "conflicts" and avoiding "mergy operations" like you did above may be a better direction to go.
Documentation/gitmergeconflicts.adoc line 16
Quoted 1 line
Documentation/gitmergeconflicts.adoc new file +1
-0+The most common ways to handle a merge conflict are:A natural paraphrase of the above is "A merge conflict is typically handled by these ways", but I thought the current readers are puzzled by "typically your side" that does not say when is typical.
Quoted 10 lines
Documentation/gitmergeconflicts.adoc line 23
Quoted 6 lines
Documentation/gitmergeconflicts.adoc new file +6
-0+* Resolve the conflict. (see <<resolve,HOW TO RESOLVE A MERGE CONFLICT>> + below for details) +* Or 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.Both are good options and I do not think of a middle way. Perhaps we do not have to say that these are "the most common" and instead say "You handle a merge conflict by doing either of these two"?
I agree the "the most common" is kind of weaselly and I'd like to be more clear. The reason I wrote "typically" is that during a rebase, there's an extra "skip" option, so it's not strictly true to say that there are just two options. Not sure if there's another option I'm not thinking of other than the "skip" in rebase.
Quoted 7 lines
Saying "return your branch to" is a bit misleading for two reasons. Conflicts presented to the users are primarily visible in their working tree files and the index. A single commit operations like 'merge', 'pull', and 'revert' does not touch your branch if they hit a conflict, and 'rebase' works on a detached HEAD, and stops without touching your branch when it sees a conflict.
Quoted 5 lines
If I were writing this, with the goal of avoiding the issues the current text has you listed in the proposed log message, I would probably say something like this:
* Or give up and return to the original state with ...
That's reasonable, I think "return to the original state" would be fine. Will look at this.
Quoted 42 lines
Documentation/gitmergeconflicts.adoc line 31
Quoted 8 lines
Documentation/gitmergeconflicts.adoc new file +7
-0+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.Many of the operations, even "git merge", is not about merging "two commits" together, but I do not think of a good way to explain it, so I accept that phrasing as a helpful white lie. I mention this because somebody else may be able to come up with a better phrasing that I (or authors of this iteration) couldn't think of.
Documentation/gitmergeconflicts.adoc line 44
Quoted 12 lines
Documentation/gitmergeconflicts.adoc new file +12
-0+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.By the way, I think we should briefly mention what sematnic merge conflicts are, and that Git does not detect them and that this manual page does not tell readers how to deal with them.
Note that non-overlapping changes from two sides may leave the result in an inconsistent state. With the edit to lines 1-5, one side may have changed the name of a function, while with the edit to lines 20-25, the other side may have added a new call to the function by its original name. This type of inconsistencies are called semantic conflicts, Git has no way knowing that a merge introduced semantic conflicts, and ends up producing a broken result without merge conflicts. This document does not cover what to do with semantic conflicts.
Quoted 2 lines
That is overly long, but perhaps you can condense it down to the essense and shrink down to 1/3 of the size.
I was thinking about that too. Maybe we can briefly mention that git's merges are not guaranteed to produce working code even when they succeed and point to an example further down the page. Added to my list of things to work on.
Quoted 10 lines
Documentation/gitmergeconflicts.adoc line 51
Quoted 6 lines
Documentation/gitmergeconflicts.adoc new file +6
-0+[[markers]] +MERGE CONFLICT MARKERS +---------------------- + +When there's a merge conflict, Git will update the conflicted file +to include merge conflict markers `<<<<<<<`, `=======`, and `>>>>>>>`.I notice that when you introduce
diff3below, you silently add|||||||to the mix without explaining what it is.
Quoted 6 lines
`|||||||` may also be used as merge conflict markers (explained later).or something along the line here may help. Or explain what it is in
diff3section. Either would work. Adding without explanation would not.
I think explaining it in the diff3 section makes sense, will do.
Quoted 17 lines
Quoted 17 lines
Documentation/gitmergeconflicts.adoc new file +17
-0+For example, here's a merge conflict where both sides edited a list of +fruits in different ways: + +---- +FRUITS = [ + "apple", +<<<<<<< HEAD + "cherry", +======= + "banana", +>>>>>>> add-fruit + "mango", + "orange", +] +---- + +The code from one side of the merge conflict is between `<<<<<<<` and
Quoted 8 lines
Documentation/gitmergeconflicts.adoc line 71
Quoted 3 lines
Documentation/gitmergeconflicts.adoc new file +3
-0+`=======`, and the code for the other side is between `=======` and +`>>>>>>>`. See <<ours,"OURS" AND "THEIRS">> below for a full explanation +of which side is which.If we said "one side wanted to have 'apple, cherry, mango, orange', while the other side wanted 'apply, banana, mango, orange', in the FRUITS array", would it help the understanding? Or is it too obvious?
I think it could make sense to add something here yes. Added to my list.
Quoted 18 lines
Quoted 18 lines
Documentation/gitmergeconflicts.adoc new file +18
-0+[[example]] +EXAMPLE OF RESOLVING A MERGE CONFLICT +------------------------------------- + +If you see this in your code during a merge conflict: + +---- +FRUITS = [ + "apple", +<<<<<<< HEAD + "cherry", + "mango", +======= + "banana", + "mango", +>>>>>>> add-fruit + "orange", +]
Quoted 8 lines
Documentation/gitmergeconflicts.adoc line 85
Quoted 1 line
Documentation/gitmergeconflicts.adoc new file +1
-0+----It would make your readers puzzled why the example is subtly different from the earlier one that showed "mango" as not touched by either side. I see this lays the groundwork for later demonstration of
diff3, so having both sides explicitly want "mango" is a good example. Perhaps update the first example to be the same as this one, which would reduce the mental burden by readers?
I very much agree it's important for the examples to match, will work on that. It's a bit tricky with diff3 like you say.
Quoted 10 lines
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+[[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
Quoted 8 lines
Documentation/gitmergeconflicts.adoc line 141
Quoted 4 lines
Documentation/gitmergeconflicts.adoc new file +4
-0+ the mergetools Git supports. + +* You can set the configuration option `merge.conflictstyle=diff3`. + See <<diff3,DIFF3 AND ZDIFF3>> below for more.These are called 'configuration variables' throughout the manual pages. Be consistent and replace "configuration option" with "configuration variable", perhaps?
They seem to be both used interchangeably already:
```
$ grep 'configuration variable' *.adoc | wc -l
256
$ grep 'configuration option' *.adoc | wc -l
46
```git-config.adoc uses the term "configuration option" 2 times and "configuration variable" once. Is there supposed to be some difference between these terms? As far as I can tell from brief history spelunking Git has used those terms interchangeably for a long time. AFAIK "configuration option" is the term more often used outside Git.
Quoted 6 lines
Documentation/gitmergeconflicts.adoc line 145
Quoted 3 lines
Documentation/gitmergeconflicts.adoc new file +3
-0+* `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.Maybe worth mentioning that
--left-rightoften helps when you are not super familiar with the histories being merged.
I don't understand what this does or what it would be useful for so it's not possible for me to explain it :). From my perspective "ours" and "theirs" are already confusing enough and introducing "left" and "right" seems like a lot. Is "left" the same as "ours"?
Quoted 7 lines
Documentation/gitmergeconflicts.adoc line 150
Quoted 4 lines
Documentation/gitmergeconflicts.adoc new file +4
-0+* 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.Maybe it will help to say we will explain "ours" and "theirs" later in this document.
Plausible, added to my todo list to look at, thanks.
Quoted 8 lines
Documentation/gitmergeconflicts.adoc line 161
Quoted 2 lines
Documentation/gitmergeconflicts.adoc new file +2
-0+* Use `git diff AUTO_MERGE` to show what changes you've made so far to + resolve the conflicts.Does a "See below" here help readers who haven't learned what
AUTO_MERGEis? If you can describe whatAUTO_MERGErecords (in other words, what you are comparing your progress against) in a sentence of two here, that would alleviate the need to assure them that we have more in-depth coverage on this topic elsewhere.
I think this is okay the way it is.
Quoted 19 lines
Quoted 4 lines
Documentation/gitmergeconflicts.adoc new file +4
-0+[[git_status]] +EXAMPLE: GIT STATUS OUTPUT +-------------------------- +Documentation/gitmergeconflicts.adoc line 176
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+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 +* there's one file left with conflicts in it: `fruits.py`There may be users, after seeing the last point, left puzzled why
fruits.pyis still listed after they edited the file like instructed in an earlier example but haven't marked the resolution.
Quoted 3 lines
fruits.pyis not marked as its conflicts resolved yet.or something?
Thanks, agreed that "there's one file left with conflicts in it: fruits.py" isn't precise enough. Will make it more accurate.
Quoted 9 lines
Quoted 9 lines
Documentation/gitmergeconflicts.adoc new file +9
-0+---- +$ 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)
Quoted 8 lines
Documentation/gitmergeconflicts.adoc line 189
Quoted 3 lines
Documentation/gitmergeconflicts.adoc new file +3
-0+ (use "git add <file>..." to mark resolution) + both modified: fruits.py +----The approach to give explanations first and then an example the explanation explains next is refreshing to me. As long as the explanations are short enough, this may work better than the usual order to say "you'd see something like this. let us explain ...".
Glad to hear it!
Quoted 4 lines
Quoted 4 lines
Documentation/gitmergeconflicts.adoc new file +4
-0+[[diff3]] +DIFF3 AND ZDIFF3 +---------------- +
Quoted 8 lines
Documentation/gitmergeconflicts.adoc line 200
Quoted 5 lines
Documentation/gitmergeconflicts.adoc new file +5
-0+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` or `zdiff3`. +This extra context can make it much easier to understand what's +happening in a merge conflict.I think most on the list considers
zdiff3a failed experiment that reduces usefulness ofdiff3. Do we want to recommend it?
I'd be extremely happy to remove this if the list doesn't think zdiff3 is useful. When I was writing this I was confused by zdiff3 and thought diff3 made a lot more sense.
Maybe we could add a note like this somewhere?
NOTE: zdiff3 was an experimental alternative to diff3 that makes the merge conflict shorter by introducing more ambiguity. It's still there for backwards compatibility but we don't recommend it.
Quoted 4 lines
By the way, is it just me who finds those "Here's", "there's" contractions disturbing in an official manual? I've seen many of them while reviewing this to be annoyed enough and had to blurt it out X-<.
I find "here is" and "there is" to be distracting and overly formal, different people are different I guess :)
Quoted 57 lines
Documentation/gitmergeconflicts.adoc line 255
Quoted 2 lines
Documentation/gitmergeconflicts.adoc new file +2
-0+"Ours" and "theirs" are both commits: "ours" is the current +`HEAD` commit, and "theirs" is the other side being merged.Now, "commits" is again a white lie. The story becomes more complicated when we talk about cherry-pick and revert, but if we primarily stick to what happens in 'merge' (which is what I've seen so far in this document), then it shouldn't add any extra difficulty to understand by saying "ours and theirs are history of changes leading to the two commits since they diverged from the original" to add clarity.
Quoted 31 lines
Documentation/gitmergeconflicts.adoc new file +31
-0+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.Documentation/gitmergeconflicts.adoc line 297
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+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.The first sentence gave me "Huh? You haven't explained what
AUTO_MERGEis yet". It may be just me, but I would have expected presentation order to be more like:
Quoted 4 lines
When merge conflicts happen, the result of merge algorithm, together with conflict markers, is recorded in
AUTO_MERGE. As you resolve conflicts, you can compare your working tree files against it withgit diff AUTO_MERGEto see your progress.
Can take a look but I don't think it makes a big difference.
Quoted 37 lines
Quoted 6 lines
Documentation/gitmergeconflicts.adoc new file +6
-0+For example, if we resolved the conflict by adding both "banana" and +"cherry" in order, the diff would look like this: + +---- + FRUITS = [ + "apple",Documentation/gitmergeconflicts.adoc line 314
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+-<<<<<<< HEAD +- "cherry", +-======= + "banana", +->>>>>>> add-fruit ++ "cherry", + "mango", + "orange", + ] +----Thanks.
I was puzzled by this
Quoted 4 lines
- In "The only clean-ups you need are to reset the index file to the
HEADcommit to reverse 2. and to clean up working tree changes made by 2. and 3.", it's not clear to users what "2" and "3" are supposed to meanand did some digging.
The text comes from
ffb1a4bed5(Documentation: Describe merge operation a bit better., 2005-11-28) that had "When there are conflicts, these things happen. 1. HEAD does not move, 2. Cleanly merged paths are updated in the index 3. Conflicts are recorded in higher stage index entries and working tree files show conflict markers, 4. No other changes are done" well before the mysterious reference to 2. and 3.
Quoted 7 lines
When
ebef7e5049(Documentation: simplify How Merge Works, 2010-01-23) tried to simplify the description, the list of "these things happen" were removed/rewritten, and yet instructions on how to reset are left behind, still referring to 2. and 3.We probably want a separate patch for
Documentation/git-merge.adocto rectify this 16 year old mistake.
Thanks for investigating!
Re: [PATCH v2 1/6] doc: add new gitmergeconflicts man page
Quoted 11 lines · Julia Evans
Quoted 10 lines
Documentation/gitmergeconflicts.adoc line 23
Quoted 6 lines
Documentation/gitmergeconflicts.adoc new file +6
-0+* Resolve the conflict. (see <<resolve,HOW TO RESOLVE A MERGE CONFLICT>> + below for details) +* Or 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.Both are good options and I do not think of a middle way. Perhaps we do not have to say that these are "the most common" and instead say "You handle a merge conflict by doing either of these two"?
Quoted 5 lines
I agree the "the most common" is kind of weaselly and I'd like to be more clear. The reason I wrote "typically" is that during a rebase, there's an extra "skip" option, so it's not strictly true to say that there are just two options. Not sure if there's another option I'm not thinking of other than the "skip" in rebase.
I do not think anything like "rebase --skip" in a multi-step integration is what this document covers particularly well to begin with. Taking each conflicted step individually, with "skip", you are stopping the operation without resolving the conflict.
Perhaps make it clear that in the above you are talking about what to do with each individual opportunity to give back conflict resolution to the command? If you describe these two choices in the context of multi-step operation, each "we stopped due to conflict and gave control back to you" opportunity gives you these choices:
* Give up, pretend this step did not exist, and continue.
* Resolve the conflict, record it, and continue.
In addition, you have "--abort" to give up the whole thing. And a single step operation like "git merge" is a degenerated case of the above. "and continue" part does not exist.
Quoted 4 lines
I was thinking about that too. Maybe we can briefly mention that git's merges are not guaranteed to produce working code even when they succeed and point to an example further down the page. Added to my list of things to work on.
It's not limited to "GIt's merges" but applies in general.
Quoted 19 lines
Quoted 10 lines
Quoted 10 lines
+[[tools]]
Documentation/gitmergeconflicts.adoc new file +9
-0+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 ofQuoted 8 lines
Documentation/gitmergeconflicts.adoc line 141
Quoted 4 lines
Documentation/gitmergeconflicts.adoc new file +4
-0+ the mergetools Git supports. + +* You can set the configuration option `merge.conflictstyle=diff3`. + See <<diff3,DIFF3 AND ZDIFF3>> below for more.These are called 'configuration variables' throughout the manual pages. Be consistent and replace "configuration option" with "configuration variable", perhaps?
Quoted 8 lines
They seem to be both used interchangeably already:
``` $ grep 'configuration variable' *.adoc | wc -l 256 $ grep 'configuration option' *.adoc | wc -l 46 ```
Do not make it worse. The latter were mostly added people like you who responds like the above; aim to be more consistent instead.
Quoted 11 lines
Quoted 6 lines
Documentation/gitmergeconflicts.adoc line 145
Quoted 3 lines
Documentation/gitmergeconflicts.adoc new file +3
-0+* `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.Maybe worth mentioning that
--left-rightoften helps when you are not super familiar with the histories being merged.I don't understand what this does or what it would be useful for so it's not possible for me to explain it :). From my perspective "ours" and "theirs" are already confusing enough and introducing "left" and "right" seems like a lot. Is "left" the same as "ours"?
If you do not understand what it does, perhaps try it out?
"git log -p --merge" is to break down the ours/theirs into individual steps when changes on these sides were brought in in multiple steps. It shows individual changes per commit, but if you are not super familiar with these histories being merged, it is not obvious which commit came from which side. And --left-right option is a way to help you tell which one came from which.
Quoted 10 lines
Quoted 8 lines
Documentation/gitmergeconflicts.adoc line 161
Quoted 2 lines
Documentation/gitmergeconflicts.adoc new file +2
-0+* Use `git diff AUTO_MERGE` to show what changes you've made so far to + resolve the conflicts.Does a "See below" here help readers who haven't learned what
AUTO_MERGEis? If you can describe whatAUTO_MERGErecords (in other words, what you are comparing your progress against) in a sentence of two here, that would alleviate the need to assure them that we have more in-depth coverage on this topic elsewhere.I think this is okay the way it is.
Is it because, unlike --left-right, you understand what it does? Not everybody shares what you know, you know ;-)
* AUTO_MERGE records the initial merge result with conflict markers. git diff AUTO_MERGE can be used to show how much progress you made to resolve these conflicts.
perhaps.
Quoted 5 lines
Maybe we could add a note like this somewhere?
NOTE: zdiff3 was an experimental alternative to diff3 that makes the merge conflict shorter by introducing more ambiguity. It's still there for backwards compatibility but we don't recommend it.
Drop "experimental" and I am 100% behind that statement ;-).
Quoted 7 lines
Quoted 4 lines
By the way, is it just me who finds those "Here's", "there's" contractions disturbing in an official manual? I've seen many of them while reviewing this to be annoyed enough and had to blurt it out X-<.
I find "here is" and "there is" to be distracting and overly formal, different people are different I guess :)
I would prefer to be consistent in a single documentation set, though.
Quoted 13 lines
Quoted 13 lines
The text comes from
ffb1a4bed5(Documentation: Describe merge operation a bit better., 2005-11-28) that had "When there are conflicts, these things happen. 1. HEAD does not move, 2. Cleanly merged paths are updated in the index 3. Conflicts are recorded in higher stage index entries and working tree files show conflict markers, 4. No other changes are done" well before the mysterious reference to 2. and 3.When
ebef7e5049(Documentation: simplify How Merge Works, 2010-01-23) tried to simplify the description, the list of "these things happen" were removed/rewritten, and yet instructions on how to reset are left behind, still referring to 2. and 3.
Quoted 4 lines
Quoted 2 lines
We probably want a separate patch for
Documentation/git-merge.adocto rectify this 16 year old mistake.Thanks for investigating!
Heh, you already did the separate patch, which is [2/6], which I am happy with.
Re: [PATCH v2 1/6] doc: add new gitmergeconflicts man page
In reply to Julia Evans"Julia Evans" <[email protected]> writes:
Comments on a few more points.
Quoted 6 lines
Quoted 3 lines
Is it deliberate to omit 'am -3' and 'checkout -m', perhaps in order to limit ourselves to most common ways to help new people by keeping the description to the absolute minimum?
It's deliberate, we talked about that a bit in the discussion of the v1. Can add a note in the commit message.
Being a part of _the_ technical manual on Git, I would like to see us aim for completeness, and where we don't leave a note that the description is not complete. In this case, between
Merge conflicts can happen during a git merge, git rebase, git cherry-pick, git pull, git am -3, git checkout -m, git stash pop, or git revert.
that aims for completeness and
Merge conflicts can happen during a git merge, git rebase, git cherry-pick, git pull, or git revert, and other operations.
that admits the list is not complete, I have slight preference to the first one.
Quoted 7 lines
Quoted 4 lines
By the way, is it just me who finds those "Here's", "there's" contractions disturbing in an official manual? I've seen many of them while reviewing this to be annoyed enough and had to blurt it out X-<.
I find "here is" and "there is" to be distracting and overly formal, different people are different I guess :)
But I wouldn't want you to be "different" here. This is not your diary or personal note. This being a part of the technical manual, I would prefer to see the same formalness applied everywhere.
PATCH v2 2/6 doc: git-merge: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
All of the info about merge conflicts has been moved to the new guide
--- Documentation/git-merge.adoc | 125 +---------------------------------- 1 file changed, 3 insertions(+), 122 deletions(-)
Documentation/git-merge.adoc +3 -122
@@ -49,7 +49,8 @@ a log message from the user describing the changes. Before the operation, A merge stops if there's a conflict that cannot be resolved automatically or if `--no-commit` was provided when initiating the merge. At that point you can run `git merge --abort` or `git merge ---continue`. +--continue`. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts. `git merge --abort` will abort the merge process and try to reconstruct the pre-merge state. However, if there were uncommitted changes when the
@@ -231,127 +232,6 @@ git merge v1.2.3^0 git merge --ff-only v1.2.3 ---- -HOW CONFLICTS ARE PRESENTED ---------------------------- - -During a merge, the working tree files are updated to reflect the result -of the merge. Among the changes made to the common ancestor's version, -non-overlapping ones (that is, you changed an area of the file while the -other side left that area intact, or vice versa) are incorporated in the -final result verbatim. When both sides made changes to the same area, -however, Git cannot randomly pick one side over the other, and asks you to -resolve it by leaving what both sides did to that area. - -By default, Git uses the same style as the one used by the "merge" program -from the RCS suite to present such a conflicted hunk, like this: - ------------- -Here are lines that are either unchanged from the common -ancestor, or cleanly resolved because only one side changed, -or cleanly resolved because both sides changed the same way. -<<<<<<< yours:sample.txt -Conflict resolution is hard; -let's go shopping. -======= -Git makes conflict resolution easy. ->>>>>>> theirs:sample.txt -And here is another line that is cleanly resolved or unmodified. ------------- - -The area where a pair of conflicting changes happened is marked with markers -+<<<<<<<+, `=======`, and +>>>>>>>+. The part before the `=======` -is typically your side, and the part afterwards is typically their side. - -The default format does not show what the original said in the conflicting -area. You cannot tell how many lines are deleted and replaced with -Barbie's remark on your side. The only thing you can tell is that your -side wants to say it is hard and you'd prefer to go shopping, while the -other side wants to claim it is easy. - -An alternative style can be used by setting the `merge.conflictStyle` -configuration variable to either `diff3` or `zdiff3`. In `diff3` -style, the above conflict may look like this: - ------------- -Here are lines that are either unchanged from the common -ancestor, or cleanly resolved because only one side changed, -<<<<<<< yours:sample.txt -or cleanly resolved because both sides changed the same way. -Conflict resolution is hard; -let's go shopping. -||||||| base:sample.txt -or cleanly resolved because both sides changed identically. -Conflict resolution is hard. -======= -or cleanly resolved because both sides changed the same way. -Git makes conflict resolution easy. ->>>>>>> theirs:sample.txt -And here is another line that is cleanly resolved or unmodified. ------------- - -while in `zdiff3` style, it may look like this: - ------------- -Here are lines that are either unchanged from the common -ancestor, or cleanly resolved because only one side changed, -or cleanly resolved because both sides changed the same way. -<<<<<<< yours:sample.txt -Conflict resolution is hard; -let's go shopping. -||||||| base:sample.txt -or cleanly resolved because both sides changed identically. -Conflict resolution is hard. -======= -Git makes conflict resolution easy. ->>>>>>> theirs:sample.txt -And here is another line that is cleanly resolved or unmodified. ------------- - -In addition to the +<<<<<<<+, `=======`, and +>>>>>>>+ markers, it uses -another +|||||||+ marker that is followed by the original text. You can -tell that the original just stated a fact, and your side simply gave in to -that statement and gave up, while the other side tried to have a more -positive attitude. You can sometimes come up with a better resolution by -viewing the original. - - -HOW TO RESOLVE CONFLICTS ------------------------- - -After seeing a conflict, you can do two things: - - * Decide not to merge. The only clean-ups you need are to reset - the index file to the `HEAD` commit to reverse 2. and to clean - up working tree changes made by 2. and 3.; `git merge --abort` - can be used for this. - - * Resolve the conflicts. Git will mark the conflicts in - the working tree. Edit the files into shape and - `git add` them to the index. Use `git commit` or - `git merge --continue` to seal the deal. The latter command - checks whether there is a (interrupted) merge in progress - before calling `git commit`. - -You can work through the conflict with a number of tools: - - * Use a mergetool. `git mergetool` to launch a graphical - mergetool which will work through the merge with you. - - * Look at the diffs. `git diff` will show a three-way diff, - highlighting changes from both the `HEAD` and `MERGE_HEAD` - versions. `git diff AUTO_MERGE` will show what changes you've - made so far to resolve textual conflicts. - - * Look at the diffs from each branch. `git log --merge -p <path>` - will show diffs first for the `HEAD` version and then the - `MERGE_HEAD` version. - - * Look at the originals. `git show :1:filename` shows the - common ancestor, `git show :2:filename` shows the `HEAD` - version, and `git show :3:filename` shows the `MERGE_HEAD` - version. - - EXAMPLES --------
@@ -406,6 +286,7 @@ linkgit:git-reset[1], linkgit:git-diff[1], linkgit:git-ls-files[1], linkgit:git-add[1], linkgit:git-rm[1], linkgit:git-mergetool[1] +linkgit:gitmergeconflicts[7] GIT ---
Signature · 1 line
gitgitgadget
Re: [PATCH v2 2/6] doc: git-merge: link to new merge conflicts guide
Quoted 3 lines · Julia Evans via GitGitGadget
From: Julia Evans <[email protected]>
All of the info about merge conflicts has been moved to the new guide
In the body text end the sentence with a full stop.
And I just went though the "new guide" with fine toothed comb, I am very much qualified to judge if the above claim is correct. Let's see.
Quoted 4 lines
Documentation/git-merge.adoc +0
-0@@ -231,127 +232,6 @@ git merge v1.2.3^0 git merge --ff-only v1.2.3 ----
Documentation/git-merge.adoc git merge v1.2.3^0 · line 243
Quoted 10 lines
Documentation/git-merge.adoc +0
-10-HOW CONFLICTS ARE PRESENTED ---------------------------- - -During a merge, the working tree files are updated to reflect the result -of the merge. Among the changes made to the common ancestor's version, -non-overlapping ones (that is, you changed an area of the file while the -other side left that area intact, or vice versa) are incorporated in the -final result verbatim. When both sides made changes to the same area, -however, Git cannot randomly pick one side over the other, and asks you to -resolve it by leaving what both sides did to that area.
OK. We said working tree files are updated. We made a weak reference to "common ancestor" but with my suggested updates I think we sufficiently cover this. "Git cannot ... and asks you ..." had a nice nuance that we may not have captured in the new document (we stop at "will not try to guess" and say "asks you to pick" in a seaprate paragraph, which feels a bit detached than the original here [***]).
Quoted 15 lines
Documentation/git-merge.adoc +0
-15-By default, Git uses the same style as the one used by the "merge" program -from the RCS suite to present such a conflicted hunk, like this: - ------------- -Here are lines that are either unchanged from the common -ancestor, or cleanly resolved because only one side changed, -or cleanly resolved because both sides changed the same way. -<<<<<<< yours:sample.txt -Conflict resolution is hard; -let's go shopping. -======= -Git makes conflict resolution easy. ->>>>>>> theirs:sample.txt -And here is another line that is cleanly resolved or unmodified. -------------
Documentation/git-merge.adoc git merge v1.2.3^0 · line 269
Quoted 10 lines
Documentation/git-merge.adoc +0
-10- -The area where a pair of conflicting changes happened is marked with markers -+<<<<<<<+, `=======`, and +>>>>>>>+. The part before the `=======` -is typically your side, and the part afterwards is typically their side. - -The default format does not show what the original said in the conflicting -area. You cannot tell how many lines are deleted and replaced with -Barbie's remark on your side. The only thing you can tell is that your -side wants to say it is hard and you'd prefer to go shopping, while the -other side wants to claim it is easy.
We covered all of the above, except for the reference to RCS which we explicitly wanted to lose. Good.
Documentation/git-merge.adoc git merge v1.2.3^0
Quoted 4 lines
Documentation/git-merge.adoc +0
-3-An alternative style can be used by setting the `merge.conflictStyle` -In addition to the +<<<<<<<+, `=======`, and +>>>>>>>+ markers, it uses -another +|||||||+ marker that is followed by the original text.
This is what we were missing in the new guide, which I tried to rectify without looking at this exact text. In any shape it should be preserved somehow [***].
Documentation/git-merge.adoc git merge v1.2.3^0 · line 315
Quoted 5 lines
- You can
Documentation/git-merge.adoc +0
-4-tell that the original just stated a fact, and your side simply gave in to -that statement and gave up, while the other side tried to have a more -positive attitude. You can sometimes come up with a better resolution by -viewing the original.
We covered this with "fruits from both sides" example, and I think the explanation there is shorter and simpler to understand.
Quoted 6 lines
Documentation/git-merge.adoc +0
-6-HOW TO RESOLVE CONFLICTS ------------------------- - -After seeing a conflict, you can do two things: - - * Decide not to merge. The only clean-ups you need are to reset
Documentation/git-merge.adoc git merge v1.2.3^0 · line 333
Quoted 10 lines
Documentation/git-merge.adoc +0
-10- the index file to the `HEAD` commit to reverse 2. and to clean - up working tree changes made by 2. and 3.; `git merge --abort` - can be used for this. - - * Resolve the conflicts. Git will mark the conflicts in - the working tree. Edit the files into shape and - `git add` them to the index. Use `git commit` or - `git merge --continue` to seal the deal. The latter command - checks whether there is a (interrupted) merge in progress - before calling `git commit`.
The new text tried to have a wiggle room with "most common", but nothing is lost from the above if we tweak it with my suggested "there are only two" [***].
Quoted 8 lines
Documentation/git-merge.adoc +0
-8-You can work through the conflict with a number of tools: - - * Use a mergetool. `git mergetool` to launch a graphical - mergetool which will work through the merge with you. - - * Look at the diffs. `git diff` will show a three-way diff, - highlighting changes from both the `HEAD` and `MERGE_HEAD` - versions. `git diff AUTO_MERGE` will show what changes you've
Documentation/git-merge.adoc git merge v1.2.3^0 · line 352
Quoted 10 lines
Documentation/git-merge.adoc +0
-10- made so far to resolve textual conflicts. - - * Look at the diffs from each branch. `git log --merge -p <path>` - will show diffs first for the `HEAD` version and then the - `MERGE_HEAD` version. - - * Look at the originals. `git show :1:filename` shows the - common ancestor, `git show :2:filename` shows the `HEAD` - version, and `git show :3:filename` shows the `MERGE_HEAD` - version.
We covered this in "Tools for handling" section. This version groups AUTO_MERGE together with other tools, which may have its advantages and disadvantages. The latter two bullet points in the above list is about static view, so is three-way O A B diff. Use of mergetool and 'diff AUTO_MERGE" are more dynamic "how far have you come" view. So separating the "git diff" that shows three-way comparison and "git diff AUTO_MERGE" in the new document sounds like an improvement (even though 'mergetool' blurs the boundary between "how the conflict looked like" and "what your eventual conflict you are working toward may look like", though [***]).
Overall, I fully agree with these removals. We may want to take a few points (marked with [***]) we learned during this review back to the new document from here, though.
Thanks.
PATCH v2 3/6 doc: git-rebase: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
Remove some of the detail about how to handle a merge conflict, since it's explained in detail in the new guide, and there probably isn't enough detail anyway.
Leave the steps since rebase is special and has a --skip option which the other commands which cause merge conflicts don't have.
--- Documentation/git-rebase.adoc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
Documentation/git-rebase.adoc +9 -4
@@ -46,10 +46,7 @@ If there is a merge conflict during this process, `git rebase` will stop at the first problematic commit and leave conflict markers. If this happens, you can do one of these things: -1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<) - and make edits to resolve the conflict. For each file you edit, you need to - tell Git that the conflict has been resolved. You can mark the conflict as - resolved with `git add <filename>`. After resolving all of the conflicts, +1. Resolve the conflict. After resolving all of the conflicts, you can continue the rebasing process with git rebase --continue
@@ -62,6 +59,9 @@ one of these things: git rebase --skip +See linkgit:gitmergeconflicts[7] (or `git help mergeconflicts`) +for a full guide to handling merge conflicts. + If you don't specify an `<upstream>` to rebase onto, the upstream configured in `branch.<name>.remote` and `branch.<name>.merge` options will be used (see linkgit:git-config[1] for details) and the `--fork-point` option is
@@ -1284,6 +1284,11 @@ include::includes/cmd-config-section-all.adoc[] include::config/rebase.adoc[] include::config/sequencer.adoc[] +SEE ALSO +-------- + +linkgit:gitmergeconflicts[7] + GIT --- Part of the linkgit:git[1] suite
Signature · 1 line
gitgitgadget
Re: [PATCH v2 3/6] doc: git-rebase: link to new merge conflicts guide
Quoted 6 lines · Julia Evans via GitGitGadget
From: Julia Evans <[email protected]>
Remove some of the detail about how to handle a merge conflict, since it's explained in detail in the new guide, and there probably isn't enough detail anyway.
Quoted 7 lines
Leave the steps since rebase is special and has a
--skipoption which the other commands which cause merge conflicts don't have.Signed-off-by Julia Evans <[email protected]>--- Documentation/git-rebase.adoc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
Great. There is nothing I would miss from these removed lines. All are already described better in the new document, with or without suggestions I made during reviews of [1/6] and [2/6].
PATCH v2 4/6 doc: git-revert: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
--- Documentation/git-revert.adoc | 5 +++++ 1 file changed, 5 insertions(+)
Documentation/git-revert.adoc +5 -0
@@ -31,6 +31,10 @@ both will discard uncommitted changes in your working directory. See "Reset, restore and revert" in linkgit:git[1] for the differences between the three commands. +If there have been new commits since the reverted commit, there may +be a merge conflict. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts. + OPTIONS ------- <commit>...::
@@ -162,6 +166,7 @@ include::config/revert.adoc[] SEE ALSO -------- linkgit:git-cherry-pick[1] +linkgit:gitmergeconflicts[7] GIT ---
Signature · 1 line
gitgitgadget
Re: [PATCH v2 4/6] doc: git-revert: link to new merge conflicts guide
Quoted 12 lines · Julia Evans via GitGitGadget
From: Julia Evans <[email protected]>
Signed-off-by Julia Evans <[email protected]>--- Documentation/git-revert.adoc | 5 +++++ 1 file changed, 5 insertions(+)Documentation/git-revert.adoc +0
-0
Documentation/git-revert.adoc both will discard uncommitted changes in your working directory. · line 37
Quoted 7 lines
Documentation/git-revert.adoc +4
-0@@ -31,6 +31,10 @@ both will discard uncommitted changes in your working directory. See "Reset, restore and revert" in linkgit:git[1] for the differences between the three commands. +If there have been new commits since the reverted commit, there may +be a merge conflict. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts. +
This is a strange thing to say. Is it worth special casing the revert of the tip commit that much? "Reverting a commit may resolt in a merge conflict" should be sufficient, I would think.
Quoted 11 lines
Documentation/git-revert.adoc +1
-0OPTIONS ------- <commit>...::@@ -162,6 +166,7 @@ include::config/revert.adoc[] SEE ALSO -------- linkgit:git-cherry-pick[1] +linkgit:gitmergeconflicts[7] GIT ---
PATCH v2 5/6 doc: git-cherry-pick: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
Remove the discussion of merge conflicts and replace it with a link to the guide.
--- Documentation/git-cherry-pick.adoc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
Documentation/git-cherry-pick.adoc +6 -5
@@ -19,8 +19,11 @@ Given one or more existing commits, apply the change each one introduces, recording a new commit for each. This requires your working tree to be clean (no modifications from the HEAD commit). -When it is not obvious how to apply a change, the following -happens: +When it is not obvious how to apply a change, there may +be a merge conflict. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts. + +When a merge conflict happens: 1. The current branch and `HEAD` pointer stay at the last commit successfully made.
@@ -36,9 +39,6 @@ happens: conflict markers `<<<<<<<` and `>>>>>>>`. 5. No other modifications are made. -See linkgit:git-merge[1] for some hints on resolving such -conflicts. - OPTIONS ------- <commit>...::
@@ -259,6 +259,7 @@ $ git cherry-pick -Xpatience topic^ <4> SEE ALSO -------- linkgit:git-revert[1] +linkgit:gitmergeconflicts[7] GIT ---
Signature · 1 line
gitgitgadget
Re: [PATCH v2 5/6] doc: git-cherry-pick: link to new merge conflicts guide
Documentation/git-cherry-pick.adoc Given one or more existing commits, apply the change each one · line 24
Quoted 5 lines · Julia Evans via GitGitGadget
Documentation/git-cherry-pick.adoc +3
-2-When it is not obvious how to apply a change, the following -happens: +When it is not obvious how to apply a change, there may +be a merge conflict. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts.
"Obvious to whom" was the first thing that came to my mind, even though the blame largely lies on the original. Can't we get rid of the above pragraph altogether, and "See new one" at the end where you replaced "See git-merge" reference below?
Quoted 22 lines
Documentation/git-cherry-pick.adoc +2
-3+When a merge conflict happens: 1. The current branch and `HEAD` pointer stay at the last commit successfully made.@@ -36,9 +39,6 @@ happens: conflict markers `<<<<<<<` and `>>>>>>>`. 5. No other modifications are made. -See linkgit:git-merge[1] for some hints on resolving such -conflicts. - OPTIONS ------- <commit>...::@@ -259,6 +259,7 @@ $ git cherry-pick -Xpatience topic^ <4> SEE ALSO -------- linkgit:git-revert[1] +linkgit:gitmergeconflicts[7] GIT ---
Re: [PATCH v2 5/6] doc: git-cherry-pick: link to new merge conflicts guide
Quoted 12 lines · Junio C Hamano
Documentation/git-cherry-pick.adoc Given one or more existing commits, apply the change each one · line 24
Quoted 5 lines · Julia Evans via GitGitGadget
Documentation/git-cherry-pick.adoc +3
-2-When it is not obvious how to apply a change, the following -happens: +When it is not obvious how to apply a change, there may +be a merge conflict. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts."Obvious to whom" was the first thing that came to my mind, even though the blame largely lies on the original. Can't we get rid of the above pragraph altogether, and "See new one" at the end where you replaced "See git-merge" reference below?
Sounds good to me. Same for the language around revert.
Quoted 22 lines
Quoted 22 lines
Documentation/git-cherry-pick.adoc +2
-3+When a merge conflict happens: 1. The current branch and `HEAD` pointer stay at the last commit successfully made.@@ -36,9 +39,6 @@ happens: conflict markers `<<<<<<<` and `>>>>>>>`. 5. No other modifications are made. -See linkgit:git-merge[1] for some hints on resolving such -conflicts. - OPTIONS ------- <commit>...::@@ -259,6 +259,7 @@ $ git cherry-pick -Xpatience topic^ <4> SEE ALSO -------- linkgit:git-revert[1] +linkgit:gitmergeconflicts[7] GIT ---
PATCH v2 6/6 doc: git-pull: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
--- Documentation/git-pull.adoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Documentation/git-pull.adoc +2 -1
@@ -38,7 +38,8 @@ or `pull.ff` with your preferred behaviour. If there's a merge conflict during the merge or rebase that you don't want to handle, you can safely abort it with `git merge --abort` or -`git rebase --abort`. +`git rebase --abort`. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts. OPTIONS -------
Signature · 1 line
gitgitgadget
Re: [PATCH v2 6/6] doc: git-pull: link to new merge conflicts guide
Quoted 12 lines · Julia Evans via GitGitGadget
From: Julia Evans <[email protected]>
Signed-off-by Julia Evans <[email protected]>--- Documentation/git-pull.adoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)Documentation/git-pull.adoc +0
-0
Documentation/git-pull.adoc or `pull.ff` with your preferred behaviour. · line 45
Quoted 9 lines
Documentation/git-pull.adoc +2
-1@@ -38,7 +38,8 @@ or `pull.ff` with your preferred behaviour. If there's a merge conflict during the merge or rebase that you don't want to handle, you can safely abort it with `git merge --abort` or -`git rebase --abort`. +`git rebase --abort`. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts. OPTIONS -------
Very good.
Quoted 1 line · Julia Evans via GitGitGadget
* [x] list reviewers in Reviewed-by
We may have a bit of misunderstanding in the process regarding this.
. Reviewed-by:, unlike the other trailers, can only be offered by the
reviewers themselves when they are completely satisfied with the patch after a detailed analysis.
is how SubmittingPatches describes it.
ReviewingGuidelines.adoc tells reviewers
If you are happy with the state of the patch series, explicitly indicate your approval (typically with a reply to the latest version's cover letter). Optionally, you can let the author know that they can add a "Reviewed-by: <you>" trailer if they resubmit the reviewed patch verbatim in a later iteration of the series.
For example, you added Ben and Patrick to the trailer of patch #1.
Quoted 6 lines
Range-diff vs v1:
1:
ad4853dc36! 1:ab0344f947[doc] Add new gitmergeconflicts man page
@@ Metadata
Author: Julia Evans <[email protected]>
Quoted 8 lines
## Commit message ##
- [doc] Add new gitmergeconflicts man page
+ doc: add new gitmergeconflicts man page
...Co-Authored-By Marie Claire LeBlanc Flanagan <[email protected]>+ Reviewed-by: D. Ben Knoble <[email protected]>
+ Reviewed-by: Patrick Steinhardt <[email protected]>Signed-off-by Julia Evans <[email protected]>
Going back to the review thread of the previous round of this patch,
https://lore.kernel.org/git/[email protected]/
2026-09-24 14:44 ` [PATCH 1/7] [doc] Add new gitmergeconflicts man page Julia Evans via GitGitGadget
2026-09-24 20:36 ` Junio C Hamano
2026-09-24 22:04 ` Junio C Hamano
2026-09-30 13:19 ` Patrick Steinhardt
2026-09-30 19:53 ` Julia Evans
2026-09-30 20:37 ` Junio C Hamano
2026-10-01 5:14 ` Patrick Steinhardt [this message]
2026-10-01 12:10 ` Julia Evans
2026-10-02 17:58 ` Junio C Hamano
2026-10-05 16:54 ` Julia Evans
2026-10-05 17:22 ` Junio C Hamano
2026-10-05 19:11 ` Julia Evans
There are many messages that reply to the cover letter of the same iteration by Ben that gave a lot of good input, and I know Patrick also helped during the discussion to improve the document. I do not think neither of them said anything about reviewed-by.
We do want to credit the reviewers of previous rounds for their input that contributed to improvements in the latest round. But the way to do so is by mentioning them on "Helped-by:" you add.
Thanks.
Quoted 11 lines · Junio C Hamano
Quoted 1 line · Julia Evans via GitGitGadget
* [x] list reviewers in Reviewed-by
We may have a bit of misunderstanding in the process regarding this.
.
Reviewed-by:, unlike the other trailers, can only be offered by the
reviewers themselves when they are completely satisfied with the patch after a detailed analysis.is how SubmittingPatches describes it.
Thanks, put this in my todo list to fix in the next round. I'll use Helped-by instead.
Quoted 21 lines · Junio C Hamano
Quoted 2 lines
"Julia Evans via GitGitGadget" <[email protected]> writes:
For example, you added Ben and Patrick to the trailer of patch #1.
Quoted 14 lines
Range-diff vs v1:
1:
ad4853dc36! 1:ab0344f947[doc] Add new gitmergeconflicts man page
@@ Metadata
Author: Julia Evans <[email protected]>## Commit message ##
- [doc] Add new gitmergeconflicts man page
+ doc: add new gitmergeconflicts man page
...Co-Authored-By Marie Claire LeBlanc Flanagan <[email protected]>+ Reviewed-by: D. Ben Knoble <[email protected]>
+ Reviewed-by: Patrick Steinhardt <[email protected]>Signed-off-by Julia Evans <[email protected]>
PS I think I just use my non-suffixed email on this project; see our .mailmap :)
Quoted 7 lines · Julia Evans via GitGitGadget
Julia Evans (6):
doc: add new gitmergeconflicts man page
doc: git-merge: link to new merge conflicts guide
doc: git-rebase: link to new merge conflicts guide
doc: git-revert: link to new merge conflicts guide
doc: git-cherry-pick: link to new merge conflicts guide
doc: git-pull: link to new merge conflicts guide
I've sent detailed reviews on #1 and commented on others.
You add my Reviewed-by: on [2/6], [3/6], and [6/6] if your new iteration uses them as-is. My suggestions to [4/6] and [5/6] are both straight-forward, so if you choose to take them literally, you can add my Reviewed-by: on them, too.
Thanks.
v3 cover Add new page on merge conflicts
In reply to Julia Evans via GitGitGadgetHandling merge conflicts is difficult, and currently Git's guidance on merge conflicts isn't giving users the information they need to navigate the process. As usual, the process I used to write this was to collect comments from Git users on the existing documentation, and then address those issues. I listed the specific issues we're aiming to solve in the first commit message in the series.
This patch series introduces a new manual page, gitmergeconflicts, which explains the process of explaining a merge conflict with examples. It also links to that new page from the commands which can cause merge conflicts, instead of trying to reexplain the process every time.
Changed in v2:
* Explain what a merge conflict is (thanks to Junio & Ben)
* rewrite the "ours" vs "theirs" section (thanks to Patrick for the comments)
* add git log --merge (thanks to Ben)
* Leave most of the content of git cherry-pick as-is, to make this patch set smaller (thanks to Junio)
* remove the SYNOPSIS since hopefully that won't be required anymore by the time this is merged
* Fix a typo in git revert (s/reverted conflict/reverted commit/)
* 's/the the/the/' (thanks to Patrick)
* s/[doc] Thing/doc: thing/ in commit messages (thanks to Tuomas)'
* squash the commit fixing the linter error (thanks to Junio)
* list reviewers in Reviewed-by
Changed in v3:
Thanks to all the comments from Junio.
* Add signoff from Marie
* In "For example, here's a merge conflict where both sides edited a list of", add a little more detail about how to interpret the merge conflict
* When we introduce a merge mention "semantic merge conflicts"
* Say "... and any other command that does a merge" when listing commands that can cause merge conflicts.
* Reviewed-by is not the right thing, use Helped-by
* Adjust phrasing in git revert and git cherry-pick man pages
* Reference the "ours" section in "git show :2:filename shows the "ours""
* "there's one file left with conflicts in it: fruits.py" isn't precise enough, instead say "the conflicts in fruits.py haven't been marked as resolved"
* Delete the explanation of zdiff3 and add a brief warning instead. Don't be too prescriptive, we should tell people what the issue is (ambiguity) instead of trying to impose our opinion.
* Explain ||||||| when we add diff3
* Fix example in "EXAMPLE OF RESOLVING A MERGE CONFLICT" to make it consistent with the other examples
* Replace "configuration option" with "configuration variable"
* Mention --skip instead of saying "the most common ways", which is ambiguous
* Add a pointer to the extended AUTO_MERGE sentence
some non-changes in v3:
* didn't add any extra Reviewed-by
* "return your branch to its original state": left the same because during a multistep cherry-pick the branch does need to be returned to its original state
* leave the explanation of AUTO_MERGE the same since Marie says it's more clear this way
* leave contractions alone for now
* don't say semantic merge applies to all merges since I think that will be clear to readers
* the wording of "When Git merges two commits together" is a bit weird but we don't have a better idea right now
* don't explain --left-right. Can be very easily added in the future if we think it's important.
Thanks to Lobo, Adam Svahn, Louis Vanier, David Turner, Ben Zanin, Salih, and about 12 others who gave feedback on both the original git merge man page, as well as the proposed improvements.
Julia Evans (6):
doc: add new gitmergeconflicts man page
doc: git-merge: link to new merge conflicts guide
doc: git-rebase: link to new merge conflicts guide
doc: git-revert: link to new merge conflicts guide
doc: git-cherry-pick: link to new merge conflicts guide
doc: git-pull: link to new merge conflicts guide
.gitattributes | 1 + Documentation/Makefile | 1 + Documentation/git-cherry-pick.adoc | 8 +- Documentation/git-merge.adoc | 125 +--------- Documentation/git-pull.adoc | 3 +- Documentation/git-rebase.adoc | 13 +- Documentation/git-revert.adoc | 5 + Documentation/gitmergeconflicts.adoc | 330 +++++++++++++++++++++++++++ Documentation/meson.build | 1 + command-list.txt | 1 + 10 files changed, 357 insertions(+), 131 deletions(-) create mode 100644 Documentation/gitmergeconflicts.adoc
base-commit: 3bc0341126508f78f5869cbfc0005e987efdf0c7
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2237%2Fjvns%2Fmerge-conflicts-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2237/jvns/merge-conflicts-v3
Pull-Request: https://github.com/gitgitgadget/git/pull/2237
Range-diff vs v2:
1: ab0344f947 ! 1: 7aa0ae7ec3 doc: add new gitmergeconflicts man page
@@ Commit message
place, since it's a really nice example of a place Git has a consistent interface between similar commands.
+ Only discuss merge, rebase, cherry-pick, and revert for now even though
+ there are other ways that merge conflicts can happen because it's
+ awkward to talk about am, apply, and checkout -m.
+
- Reviewed-by: D. Ben Knoble <[email protected]>
- Reviewed-by: Patrick Steinhardt <[email protected]>
+ Helped-by: D. Ben Knoble <[email protected]>
+ Helped-by: Patrick Steinhardt <[email protected]>
+ Signed-off-by: Julia Evans <[email protected]>
+ Signed-off-by: Marie Claire LeBlanc Flanagan <[email protected]>
## .gitattributes ##
@@ Documentation/gitmergeconflicts.adoc (new)
+-----------
+
+Merge conflicts can happen during a git merge, git rebase, `git
-+cherry-pick, git pull, or git revert`. All of those commands use -+the same merge algorithm, and the process for resolving a merge conflict -+is always very similar.
++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.
+
-+The most common ways to handle a merge conflict are:
++There are 3 ways to handle a merge conflict:
+
+* Resolve the conflict. (see <<resolve,HOW TO RESOLVE A MERGE CONFLICT>>
+ below for details)
-+* Or stop the operation and return your branch to its original state ++* 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?
+-------------------------
@@ Documentation/gitmergeconflicts.adoc (new)
+ 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
+----------------------
@@ Documentation/gitmergeconflicts.adoc (new)
+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:
++fruits in different ways -- one side added "cherry" and the other side ++added "banana":
+
+----
+FRUITS = [
@@ Documentation/gitmergeconflicts.adoc (new)
+ "apple",
+<<<<<<< HEAD
+ "cherry",
-+ "mango",
+=======
+ "banana",
-+ "mango",
+>>>>>>> add-fruit
++ "mango",
+ "orange",
+]
+----
@@ Documentation/gitmergeconflicts.adoc (new)
+ See also merge.tool in linkgit:git-config[1] for a list of
+ the mergetools Git supports.
+
-+* You can set the configuration option merge.conflictstyle=diff3. -+ See <<diff3,DIFF3 AND ZDIFF3>> below for more.
++* 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
@@ Documentation/gitmergeconflicts.adoc (new)
+* 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.
++ 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:
+
@@ Documentation/gitmergeconflicts.adoc (new)
+
+* 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
@@ Documentation/gitmergeconflicts.adoc (new)
+ original state
+* you should run git rebase --continue when you're done resolving all
+ the conflicts
-+* there's one file left with conflicts in it: fruits.py
++* the conflicts in fruits.py haven't been marked as resolved
+
+----
+$ git status
@@ Documentation/gitmergeconflicts.adoc (new)
+
+
+[[diff3]]
-+DIFF3 AND ZDIFF3
-+----------------
++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 or zdiff3. ++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. It shows, in order, the "ours" side of the conflict, the -+original code ("mangoooo"), and the "theirs" side of the -+conflict. With this view, you can see that both sides fixed the spelling ++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 added one fruit to the list.
+
+----
@@ Documentation/gitmergeconflicts.adoc (new)
+]
+----
+
-+Here's the same example using zdiff3. zdiff3 takes lines that are -+shared between both sides (the "mango" line) and moves them outside -+the conflicted area. This makes the conflicted area shorter, but the -+downside is that it's impossible to tell if "mango" was part of the -+original list of fruits or not.
-+
-+----
-+FRUITS = [
-+ "apple",
-+<<<<<<< HEAD
-+ "cherry",
-+||||||| 1c22e48
-+ "mangoooo",
-+=======
-+ "banana",
-+>>>>>>> add-fruit
-+ "mango",
-+ "orange",
-+]
-+----
-+
++[NOTE]
++================================
++zdiff3 is an alternative to diff3 that makes the merge conflict ++shorter by making it more ambiguous.
++================================
+
+[[ours]]
+"OURS" AND "THEIRS"
2: d5241eb901 = 2: 8bdbd64ca3 doc: git-merge: link to new merge conflicts guide 3: 72b1207045 = 3: 34ba85fcad doc: git-rebase: link to new merge conflicts guide 4: cfa0a8254a ! 4: 85e117b070 doc: git-revert: link to new merge conflicts guide
@@ Documentation/git-revert.adoc: both will discard uncommitted changes in your wor
See "Reset, restore and revert" in linkgit:git[1] for the differences between the three commands.
-+If there have been new commits since the reverted commit, there may -+be a merge conflict. See linkgit:gitmergeconflicts[7]
-+(or git help mergeconflicts) for a guide to handling merge conflicts. ++Reverting a commit may result in a merge conflict.
++See linkgit:gitmergeconflicts[7] (or git help mergeconflicts) ++for a guide to handling merge conflicts.
+
OPTIONS
-------
5: 62b70e9a02 ! 5: f99c99f955 doc: git-cherry-pick: link to new merge conflicts guide
@@ Documentation/git-cherry-pick.adoc: Given one or more existing commits, apply th
-When it is not obvious how to apply a change, the following -happens:
-+When it is not obvious how to apply a change, there may -+be a merge conflict. See linkgit:gitmergeconflicts[7] -+(or git help mergeconflicts) for a guide to handling merge conflicts. -+
+When a merge conflict happens:
1. The current branch and HEAD pointer stay at the last commit
@@ Documentation/git-cherry-pick.adoc: happens:
-See linkgit:git-merge[1] for some hints on resolving such -conflicts.
--
++See linkgit:gitmergeconflicts[7] (or git help mergeconflicts) ++for a guide to handling merge conflicts.
+
OPTIONS
-------
- <commit>...::
@@ Documentation/git-cherry-pick.adoc: $ git cherry-pick -Xpatience topic^ <4>
SEE ALSO
--------
6: ac77db6762 = 6: 7831b77178 doc: git-pull: link to new merge conflicts guide
Signature · 1 line
gitgitgadget
PATCH v3 1/6 doc: add new gitmergeconflicts man page
From: Julia Evans <[email protected]>
Introduce a new page, gitmergeconflicts, that explains the process of handling a merge conflict in a way that addresses the following issues, which came from feedback from Git users on the current explanation of merge conflicts in the git merge man page:
- The process for resolving a merge conflict is only explained in the git merge man page, even though there are several other commands which can result in conflicts
- Sometimes we use "ours" and "theirs" to refer to the two sides of the merge conflicts and sometimes we use HEAD and MERGE_HEAD. It should be consistent. Also the terms "ours" and "theirs" are not explained. Similarly, it says "The part before the ======= is typically your side...", but doesn't explain what "typically" means.
- It introduces the merge format using an analogy to RCS, which very few Git users have ever used
- In "The only clean-ups you need are to reset the index file to the HEAD commit to reverse 2. and to clean up working tree changes made by 2. and 3.", it's not clear to users what "2" and "3" are supposed to mean
- It uses a cultural reference ("Conflict resolution is hard; let's go shopping.") which is confusing or unfamiliar to some people. I think it would be clearer for users to use a code example instead.
- It doesn't explain the difference between diff3 and zdiff3
- It sometimes uses the term "area" and sometimes uses the term "hunk"
Also document the unified --abort, --continue workflow in one place, since it's a really nice example of a place Git has a consistent interface between similar commands.
Only discuss merge, rebase, cherry-pick, and revert for now even though there are other ways that merge conflicts can happen because it's awkward to talk about am, apply, and checkout -m.
--- .gitattributes | 1 + Documentation/Makefile | 1 + Documentation/gitmergeconflicts.adoc | 330 +++++++++++++++++++++++++++ Documentation/meson.build | 1 + command-list.txt | 1 + 5 files changed, 334 insertions(+) create mode 100644 Documentation/gitmergeconflicts.adoc
.gitattributes +1 -0
@@ -14,6 +14,7 @@ CODE_OF_CONDUCT.md -whitespace /t/oid-info/* text eol=lf /Documentation/git-merge.adoc conflict-marker-size=32 /Documentation/git-merge-file.adoc conflict-marker-size=32 +/Documentation/gitmergeconflicts.adoc conflict-marker-size=32 /Documentation/gitk.adoc conflict-marker-size=32 /Documentation/user-manual.adoc conflict-marker-size=32 /t/t????-*.sh conflict-marker-size=32
Documentation/Makefile +1 -0
@@ -58,6 +58,7 @@ MAN7_TXT += gitdiffcore.adoc MAN7_TXT += giteveryday.adoc MAN7_TXT += gitfaq.adoc MAN7_TXT += gitglossary.adoc +MAN7_TXT += gitmergeconflicts.adoc MAN7_TXT += gitpacking.adoc MAN7_TXT += gitnamespaces.adoc MAN7_TXT += gitremote-helpers.adoc
Documentation/gitmergeconflicts.adoc new file +330 -0
330 lines not on this page · raw message
Documentation/meson.build +1 -0
@@ -202,6 +202,7 @@ manpages = { 'gitfaq.adoc' : 7, 'gitglossary.adoc' : 7, 'gitpacking.adoc' : 7, + 'gitmergeconflicts.adoc' : 7, 'gitnamespaces.adoc' : 7, 'gitremote-helpers.adoc' : 7, 'gitrevisions.adoc' : 7,
command-list.txt +1 -0
@@ -232,6 +232,7 @@ githooks userinterfaces gitignore userinterfaces gitk mainporcelain gitmailmap userinterfaces +gitmergeconflicts guide gitmodules userinterfaces gitnamespaces guide gitprotocol-capabilities developerinterfaces
Signature · 1 line
gitgitgadget
Re: [PATCH v3 1/6] doc: add new gitmergeconflicts man page
Quoted 10 lines · Julia Evans via GitGitGadget
From: Julia Evans <[email protected]>
Introduce a new page,
gitmergeconflicts, that explains the process of handling a merge conflict in a way that addresses the following issues, which came from feedback from Git users on the current explanation of merge conflicts in thegit mergeman page:- The process for resolving a merge conflict is only explained in the
...
- It sometimes uses the term "area" and sometimes uses the term "hunk"
It looks a bit annoying that these sentences in the enumeration all lack their full stops.
Quoted 3 lines
Only discuss merge, rebase, cherry-pick, and revert for now even though there are other ways that merge conflicts can happen because it's awkward to talk about
am,apply, andcheckout -m.
I do not know "because it's awkward" is a good justification, though. "awkward" why?
It might be tempting to omit some commands that are less common for new users, but we are touching the main part of the technical manual that are meant ot be used by everybody, so that is not a good reason to choose covering some but not others.
I however agree that it is better to avoid appearing to be complete and leaving others (including future ones we add) with "any other command that does a merge" as this round of document gives.
Documentation/gitmergeconflicts.adoc line 25
Quoted 12 lines
Documentation/gitmergeconflicts.adoc +10
-0+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
The third entry is a nice addition. multi-step anything are the same, including revert, right? I'd recommend updating it to something like "if you are in a multi-step operation like rebase" in the same spirit as the "or any other command" change you made at the beginning of this file.
Documentation/gitmergeconflicts.adoc line 54
Quoted 7 lines
+[NOTE]
+================================Documentation/gitmergeconflicts.adoc +5
-0+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". +================================
OK.
Documentation/gitmergeconflicts.adoc line 64
Quoted 5 lines
Documentation/gitmergeconflicts.adoc +5
-0+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 added "cherry" and the other side +added "banana":
You added "-- one side added ..." at the end, which I think sends a wrong message. With rcs-merge style conflict, you cannot simply tell, because it is ambiguous. The original may have had both banana and cherry, in which case the sample output shows the result of one side removing banana and the other side removing cherry.
The only thing you can say from the sample output below is in the current state "one side has cherry where the other side has banana, and everything else is the same". You cannot say more without seeing diff3 style conflict.
Quoted 42 lines
+----
Documentation/gitmergeconflicts.adoc +37
-0+FRUITS = [ + "apple", +<<<<<<< HEAD + "cherry", +======= + "banana", +>>>>>>> add-fruit + "mango", + "orange", +] +---- + +The code from one side of the merge conflict is between `<<<<<<<` and +`=======`, and the code for the other side is between `=======` and +`>>>>>>>`. See <<ours,"OURS" AND "THEIRS">> below for a full explanation +of which side is which. +[[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:
Documentation/gitmergeconflicts.adoc line 135
Quoted 10 lines
Documentation/gitmergeconflicts.adoc +10
-0+ +---- +FRUITS = [ + "apple", + "banana", + "cherry", + "mango", + "orange", +] +----
So, this is one possible resolution. We cannot tell if it is the correct one.
Documentation/gitmergeconflicts.adoc line 142
Quoted 6 lines
+[[tools]]
Documentation/gitmergeconflicts.adoc +4
-0+TOOLS FOR HANDLING MERGE CONFLICTS +---------------------------------- + +Here are some ways to get extra context while handling a merge conflict:
The incremental changes to this list looks good.
Quoted 22 lines
+[[diff3]]
Documentation/gitmergeconflicts.adoc +21
-0+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. + +With this view, you can see that both sides fixed a spelling +mistake in "mango", and each added one fruit to the list. + +---- +FRUITS = [ + "apple", +<<<<<<< HEAD + "cherry",
Documentation/gitmergeconflicts.adoc line 235
Quoted 10 lines
Documentation/gitmergeconflicts.adoc +10
-0+ "mango", +||||||| 1c22e48 + "mangoooo", +======= + "banana", + "mango", +>>>>>>> add-fruit + "orange", +] +----
THis is a great example.
But an even better example would be to give this:
FRUITS = [
"apple",
<<<<<<< HEAD
"cherry",
"mango",
||||||| 1c22e48
"banana",
"cherry",
"mangoooo",
=======
"banana",
"mango",
>>>>>>> add-fruit
"orange",
]and tell the readers that that the correct resolution is to have "apply, mango, orange", as each of cherry and banana was removed by one side while the other side did not touch it. Having cherry and banana in the result is a tempting but not always correct conclusion unexperienced people would draw from the rcs-merge style output that is ambiguous, and here is a great place to teach it in this flow.
Especially because it would make it stand out that the point of diff3's verboseness compared to the rcs-merge output is to disambiguate two cases. If you start from ABCmO and one side has ABMO while the other side has ACMO, the right resolution would be AMO (the above case I added), but if your starting point were AmO and the two sides ends with ABMO and ACMO respectively, the right resolution would be ABCMO. The rcs-merge output does not tell you which is more likely to be correct, diff3 disambiguates these two cases by being more verbose.
And telling that value of diff3 is about disambiguating is valuable when ...
Quoted 5 lines
+[NOTE]
+================================
+zdiff3is an alternative todiff3that makes the merge conflict +shorter by making it more ambiguous.
+================================
... this note tells the readers that zdiff3 is a ambigous variant of diff3, hinting its flaw.
Re: [PATCH v3 1/6] doc: add new gitmergeconflicts man page
Quoted 9 lines · Junio C Hamano
Quoted 7 lines · Julia Evans via GitGitGadget
From: Julia Evans <[email protected]>
Introduce a new page,
gitmergeconflicts, that explains the process of handling a merge conflict in a way that addresses the following issues, which came from feedback from Git users on the current explanation of merge conflicts in thegit mergeman page:
Quoted 6 lines
Quoted 3 lines
- The process for resolving a merge conflict is only explained in the
...
- It sometimes uses the term "area" and sometimes uses the term "hunk"It looks a bit annoying that these sentences in the enumeration all lack their full stops.
Sure, will fix.
Quoted 6 lines
Quoted 3 lines
Only discuss merge, rebase, cherry-pick, and revert for now even though there are other ways that merge conflicts can happen because it's awkward to talk about
am,apply, andcheckout -m.I do not know "because it's awkward" is a good justification, though. "awkward" why?
It's because apply and am can also apply patches, and that's a whole separate topic than explaining the 3-way merge. I think explaining the difference between applying a patch and doing a 3-way merge could be interesting to do in the future but this is already quite a big patch series.
Quoted 19 lines
It might be tempting to omit some commands that are less common for new users, but we are touching the main part of the technical manual that are meant ot be used by everybody, so that is not a good reason to choose covering some but not others.
I however agree that it is better to avoid appearing to be complete and leaving others (including future ones we add) with "any other command that does a merge" as this round of document gives.
Quoted 10 lines
Documentation/gitmergeconflicts.adoc +8
-0+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.
Quoted 8 lines
Documentation/gitmergeconflicts.adoc line 25
Quoted 2 lines
Documentation/gitmergeconflicts.adoc +2
-0+* Or (if you're in a multi-step rebase or cherry-pick) skip the problematic + commit with the appropriate `--skip` commandThe third entry is a nice addition. multi-step anything are the same, including revert, right? I'd recommend updating it to something like "if you are in a multi-step operation like
rebase" in the same spirit as the "or any other command" change you made at the beginning of this file.
Done.
Quoted 11 lines
Documentation/gitmergeconflicts.adoc line 64
Quoted 5 lines
Documentation/gitmergeconflicts.adoc +5
-0+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 added "cherry" and the other side +added "banana":You added "-- one side added ..." at the end, which I think sends a wrong message. With rcs-merge style conflict, you cannot simply tell, because it is ambiguous. The original may have had both banana and cherry, in which case the sample output shows the result of one side removing banana and the other side removing cherry.
Make sense, will replace "added" with "has".
Quoted 53 lines
Quoted 22 lines
+[[diff3]]
Documentation/gitmergeconflicts.adoc +21
-0+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. + +With this view, you can see that both sides fixed a spelling +mistake in "mango", and each added one fruit to the list. + +---- +FRUITS = [ + "apple", +<<<<<<< HEAD + "cherry",Documentation/gitmergeconflicts.adoc line 235
Quoted 10 lines
Documentation/gitmergeconflicts.adoc +10
-0+ "mango", +||||||| 1c22e48 + "mangoooo", +======= + "banana", + "mango", +>>>>>>> add-fruit + "orange", +] +----THis is a great example.
But an even better example would be to give this:
FRUITS = [ "apple", <<<<<<< HEAD "cherry", "mango", ||||||| 1c22e48 "banana", "cherry", "mangoooo", ======= "banana", "mango", >>>>>>> add-fruit "orange", ]
Quoted 6 lines
and tell the readers that that the correct resolution is to have "apply, mango, orange", as each of cherry and banana was removed by one side while the other side did not touch it. Having cherry and banana in the result is a tempting but not always correct conclusion unexperienced people would draw from the rcs-merge style output that is ambiguous, and here is a great place to teach it in this flow.
Thanks, this is a much better example, for the reasons you say. Will use it.
I always appreciate thinking carefully about which examples to give, it's so important.
Quoted 21 lines
Especially because it would make it stand out that the point of diff3's verboseness compared to the rcs-merge output is to disambiguate two cases. If you start from ABCmO and one side has ABMO while the other side has ACMO, the right resolution would be AMO (the above case I added), but if your starting point were AmO and the two sides ends with ABMO and ACMO respectively, the right resolution would be ABCMO. The rcs-merge output does not tell you which is more likely to be correct, diff3 disambiguates these two cases by being more verbose.
And telling that value of diff3 is about disambiguating is valuable when ...
Quoted 5 lines
+[NOTE]
+================================
+zdiff3is an alternative todiff3that makes the merge conflict +shorter by making it more ambiguous.
+================================... this note tells the readers that zdiff3 is a ambigous variant of diff3, hinting its flaw.
Re: [PATCH v3 1/6] doc: add new gitmergeconflicts man page
Quoted 8 lines · Julia Evans
Quoted 2 lines
I do not know "because it's awkward" is a good justification, though. "awkward" why?
It's because
applyandamcan also apply patches, and that's a whole separate topic than explaining the 3-way merge. I think explaining the difference between applying a patch and doing a 3-way merge could be interesting to do in the future but this is already quite a big patch series.
I do not quite follow. "apply -3" is making a 3-way merge among the state _your_ working tree is in, the state shown as the preimage in the patch (i.e., before the patch author had the change they gave you in the patch), and the state shown as the postimage in the patch (i.e., after the patch author made the change).
It is no different from the case where cherry-picking the change the patch author had stopped in conflict if (1) the machinery did find the necessary preimage blobs and (2) the 3way application did stop in a conflict.
Quoted 3 lines
Quoted 3 lines
I however agree that it is better to avoid appearing to be complete and leaving others (including future ones we add) with "any other command that does a merge" as this round of document gives.
Thanks.
Re: [PATCH v3 1/6] doc: add new gitmergeconflicts man page
In reply to Julia Evans via GitGitGadgetQuoted 21 lines · Julia Evans via GitGitGadget
Documentation/gitmergeconflicts.adoc new file +15
-0@@ -0,0 +1,330 @@ +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. +
Documentation/gitmergeconflicts.adoc line 25
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+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
Nit: the punctuation is a bit inconsistent, where the second bullet point has a trailing punctuation mark but the other two don't.
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+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
Documentation/gitmergeconflicts.adoc line 46
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+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.
Same nit here.
Documentation/gitmergeconflicts.adoc line 54
Quoted 7 lines
Documentation/gitmergeconflicts.adoc new file +7
-0+[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". +================================
Good callout. We may also want to spell out the consequence of this:
"You should always verify the result of a merge regardless of whether or not it has resulted in a conflict.".
Quoted 5 lines
Documentation/gitmergeconflicts.adoc new file +5
-0+[[resolve]] +HOW TO RESOLVE A MERGE CONFLICT +------------------------------- + +The process for resolving a merge conflict is:
Documentation/gitmergeconflicts.adoc line 99
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+ +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.
Same nit regarding punctuation. Or is this actually a thing, where you add punctuation in case it's multiple sentences but not in the case where it's a single sentence, only? Maybe this is just me not being a native speaker.
Quoted 6 lines
Documentation/gitmergeconflicts.adoc new file +6
-0+[[tools]] +TOOLS FOR HANDLING MERGE CONFLICTS +---------------------------------- + +Here are some ways to get extra context while handling a merge conflict: +
Documentation/gitmergeconflicts.adoc line 153
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+* 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
Should we spell this out as --patch instead? That's way easier to grep in the manpage in case the reader is curious what the option does.
Documentation/gitmergeconflicts.adoc line 241
Quoted 5 lines
Documentation/gitmergeconflicts.adoc new file +5
-0+[NOTE] +================================ +`zdiff3` is an alternative to `diff3` that makes the merge conflict +shorter by making it more ambiguous. +================================
"making it more ambiguous" reads rather curious. Should we maybe take inspiration from its documentation and instead say "by removing matching lines on the two sides from the beginning or end of a conflict region"?
Documentation/gitmergeconflicts.adoc line 252
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+[[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.
They may not always be commits, but they are always tree-ishs. But I think it's fine to leave this as-is anyway, as the normal user is never going to encounter cases where it's not in fact a commit. And when they do they probably don't need this manpage anyway.
Other than this handful of nits I'm happy with this version, thanks!
Patrick
Re: [PATCH v3 1/6] doc: add new gitmergeconflicts man page
Quoted 27 lines · Patrick Steinhardt
Quoted 26 lines · Julia Evans via GitGitGadget
Documentation/gitmergeconflicts.adoc new file +20
-0@@ -0,0 +1,330 @@ +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
Quoted 8 lines
Documentation/gitmergeconflicts.adoc line 25
Quoted 5 lines
Documentation/gitmergeconflicts.adoc new file +5
-0+ 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` commandNit: the punctuation is a bit inconsistent, where the second bullet point has a trailing punctuation mark but the other two don't.
Thanks, tried to make this a bit more consistent. I think I have some slightly idiosyncratic personal rules for punctuation in bulleted lists that I don't feel very attached to.
Quoted 23 lines
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+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 willDocumentation/gitmergeconflicts.adoc line 46
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+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.Same nit here.
Quoted 11 lines
Documentation/gitmergeconflicts.adoc line 54
Quoted 7 lines
Documentation/gitmergeconflicts.adoc new file +7
-0+[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". +================================Good callout. We may also want to spell out the consequence of this:
"You should always verify the result of a merge regardless of whether or not it has resulted in a conflict.".
I think we should let people use their own judgment about how to use this information.
Quoted 32 lines
Quoted 5 lines
Documentation/gitmergeconflicts.adoc new file +5
-0+[[resolve]] +HOW TO RESOLVE A MERGE CONFLICT +------------------------------- + +The process for resolving a merge conflict is:Documentation/gitmergeconflicts.adoc line 99
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+ +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.Same nit regarding punctuation. Or is this actually a thing, where you add punctuation in case it's multiple sentences but not in the case where it's a single sentence, only? Maybe this is just me not being a native speaker.
Quoted 11 lines
Documentation/gitmergeconflicts.adoc new file +11
-0+[[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.
Quoted 8 lines
Documentation/gitmergeconflicts.adoc line 153
Quoted 5 lines
Documentation/gitmergeconflicts.adoc new file +5
-0+ +* You can set the configuration variable `merge.conflictstyle=diff3`. + See <<diff3,DIFF3>> below for more. + +* `git log --merge -p <filename>` will list all commits whichShould we spell this out as
--patchinstead? That's way easier to grep in the manpage in case the reader is curious what the option does.
Good idea, will do.
Quoted 9 lines
Documentation/gitmergeconflicts.adoc line 241
Quoted 5 lines
Documentation/gitmergeconflicts.adoc new file +5
-0+[NOTE] +================================ +`zdiff3` is an alternative to `diff3` that makes the merge conflict +shorter by making it more ambiguous. +================================"making it more ambiguous" reads rather curious. Should we maybe take inspiration from its documentation and instead say "by removing matching lines on the two sides from the beginning or end of a conflict region"?
Hmm, I've gone back and forth a lot on how to explain zdiff3, from
1. Here's how it works and here's an example to illustrate
2. You shouldn't use it
3. You may want to use it but be aware that it's ambiguous
4. Here's more info about about how it works
I think Junio's diff3 example does a really good job of making it clear why diff3 might be useful. The previous zdiff3 example I had that talked about the pros and cons of using zdiff3 didn't feel very compelling to me and I don't know how to write a good one. I think a good example probably does exist, but we might actually need multiple examples (both to show how zdiff can be useful and to show the issues).
Perhaps given that we seem to not necessarily want to recommend zdiff3, we can just not mention zdiff3 for now and add it back later if/when we feel more confident about how to explain it. I'll try just deleting the note.
Quoted 7 lines
Quoted 7 lines
Documentation/gitmergeconflicts.adoc new file +7
-0+[[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`.
Quoted 8 lines
Documentation/gitmergeconflicts.adoc line 252
Quoted 3 lines
Documentation/gitmergeconflicts.adoc new file +3
-0+ +"Ours" and "theirs" are both commits: "ours" is the current +`HEAD` commit, and "theirs" is the other side being merged.They may not always be commits, but they are always tree-ishs. But I think it's fine to leave this as-is anyway, as the normal user is never going to encounter cases where it's not in fact a commit. And when they do they probably don't need this manpage anyway.
Interesting, I didn't know it could be something other than a commit.
Quoted 4 lines
Other than this handful of nits I'm happy with this version, thanks!
Patrick
thanks for the review!
PATCH v3 2/6 doc: git-merge: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
All of the info about merge conflicts has been moved to the new guide
--- Documentation/git-merge.adoc | 125 +---------------------------------- 1 file changed, 3 insertions(+), 122 deletions(-)
Documentation/git-merge.adoc +3 -122
@@ -49,7 +49,8 @@ a log message from the user describing the changes. Before the operation, A merge stops if there's a conflict that cannot be resolved automatically or if `--no-commit` was provided when initiating the merge. At that point you can run `git merge --abort` or `git merge ---continue`. +--continue`. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts. `git merge --abort` will abort the merge process and try to reconstruct the pre-merge state. However, if there were uncommitted changes when the
@@ -231,127 +232,6 @@ git merge v1.2.3^0 git merge --ff-only v1.2.3 ---- -HOW CONFLICTS ARE PRESENTED ---------------------------- - -During a merge, the working tree files are updated to reflect the result -of the merge. Among the changes made to the common ancestor's version, -non-overlapping ones (that is, you changed an area of the file while the -other side left that area intact, or vice versa) are incorporated in the -final result verbatim. When both sides made changes to the same area, -however, Git cannot randomly pick one side over the other, and asks you to -resolve it by leaving what both sides did to that area. - -By default, Git uses the same style as the one used by the "merge" program -from the RCS suite to present such a conflicted hunk, like this: - ------------- -Here are lines that are either unchanged from the common -ancestor, or cleanly resolved because only one side changed, -or cleanly resolved because both sides changed the same way. -<<<<<<< yours:sample.txt -Conflict resolution is hard; -let's go shopping. -======= -Git makes conflict resolution easy. ->>>>>>> theirs:sample.txt -And here is another line that is cleanly resolved or unmodified. ------------- - -The area where a pair of conflicting changes happened is marked with markers -+<<<<<<<+, `=======`, and +>>>>>>>+. The part before the `=======` -is typically your side, and the part afterwards is typically their side. - -The default format does not show what the original said in the conflicting -area. You cannot tell how many lines are deleted and replaced with -Barbie's remark on your side. The only thing you can tell is that your -side wants to say it is hard and you'd prefer to go shopping, while the -other side wants to claim it is easy. - -An alternative style can be used by setting the `merge.conflictStyle` -configuration variable to either `diff3` or `zdiff3`. In `diff3` -style, the above conflict may look like this: - ------------- -Here are lines that are either unchanged from the common -ancestor, or cleanly resolved because only one side changed, -<<<<<<< yours:sample.txt -or cleanly resolved because both sides changed the same way. -Conflict resolution is hard; -let's go shopping. -||||||| base:sample.txt -or cleanly resolved because both sides changed identically. -Conflict resolution is hard. -======= -or cleanly resolved because both sides changed the same way. -Git makes conflict resolution easy. ->>>>>>> theirs:sample.txt -And here is another line that is cleanly resolved or unmodified. ------------- - -while in `zdiff3` style, it may look like this: - ------------- -Here are lines that are either unchanged from the common -ancestor, or cleanly resolved because only one side changed, -or cleanly resolved because both sides changed the same way. -<<<<<<< yours:sample.txt -Conflict resolution is hard; -let's go shopping. -||||||| base:sample.txt -or cleanly resolved because both sides changed identically. -Conflict resolution is hard. -======= -Git makes conflict resolution easy. ->>>>>>> theirs:sample.txt -And here is another line that is cleanly resolved or unmodified. ------------- - -In addition to the +<<<<<<<+, `=======`, and +>>>>>>>+ markers, it uses -another +|||||||+ marker that is followed by the original text. You can -tell that the original just stated a fact, and your side simply gave in to -that statement and gave up, while the other side tried to have a more -positive attitude. You can sometimes come up with a better resolution by -viewing the original. - - -HOW TO RESOLVE CONFLICTS ------------------------- - -After seeing a conflict, you can do two things: - - * Decide not to merge. The only clean-ups you need are to reset - the index file to the `HEAD` commit to reverse 2. and to clean - up working tree changes made by 2. and 3.; `git merge --abort` - can be used for this. - - * Resolve the conflicts. Git will mark the conflicts in - the working tree. Edit the files into shape and - `git add` them to the index. Use `git commit` or - `git merge --continue` to seal the deal. The latter command - checks whether there is a (interrupted) merge in progress - before calling `git commit`. - -You can work through the conflict with a number of tools: - - * Use a mergetool. `git mergetool` to launch a graphical - mergetool which will work through the merge with you. - - * Look at the diffs. `git diff` will show a three-way diff, - highlighting changes from both the `HEAD` and `MERGE_HEAD` - versions. `git diff AUTO_MERGE` will show what changes you've - made so far to resolve textual conflicts. - - * Look at the diffs from each branch. `git log --merge -p <path>` - will show diffs first for the `HEAD` version and then the - `MERGE_HEAD` version. - - * Look at the originals. `git show :1:filename` shows the - common ancestor, `git show :2:filename` shows the `HEAD` - version, and `git show :3:filename` shows the `MERGE_HEAD` - version. - - EXAMPLES --------
@@ -406,6 +286,7 @@ linkgit:git-reset[1], linkgit:git-diff[1], linkgit:git-ls-files[1], linkgit:git-add[1], linkgit:git-rm[1], linkgit:git-mergetool[1] +linkgit:gitmergeconflicts[7] GIT ---
Signature · 1 line
gitgitgadget
PATCH v3 3/6 doc: git-rebase: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
Remove some of the detail about how to handle a merge conflict, since it's explained in detail in the new guide, and there probably isn't enough detail anyway.
Leave the steps since rebase is special and has a --skip option which the other commands which cause merge conflicts don't have.
--- Documentation/git-rebase.adoc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
Documentation/git-rebase.adoc +9 -4
@@ -46,10 +46,7 @@ If there is a merge conflict during this process, `git rebase` will stop at the first problematic commit and leave conflict markers. If this happens, you can do one of these things: -1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<) - and make edits to resolve the conflict. For each file you edit, you need to - tell Git that the conflict has been resolved. You can mark the conflict as - resolved with `git add <filename>`. After resolving all of the conflicts, +1. Resolve the conflict. After resolving all of the conflicts, you can continue the rebasing process with git rebase --continue
@@ -62,6 +59,9 @@ one of these things: git rebase --skip +See linkgit:gitmergeconflicts[7] (or `git help mergeconflicts`) +for a full guide to handling merge conflicts. + If you don't specify an `<upstream>` to rebase onto, the upstream configured in `branch.<name>.remote` and `branch.<name>.merge` options will be used (see linkgit:git-config[1] for details) and the `--fork-point` option is
@@ -1284,6 +1284,11 @@ include::includes/cmd-config-section-all.adoc[] include::config/rebase.adoc[] include::config/sequencer.adoc[] +SEE ALSO +-------- + +linkgit:gitmergeconflicts[7] + GIT --- Part of the linkgit:git[1] suite
Signature · 1 line
gitgitgadget
PATCH v3 4/6 doc: git-revert: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
--- Documentation/git-revert.adoc | 5 +++++ 1 file changed, 5 insertions(+)
Documentation/git-revert.adoc +5 -0
@@ -31,6 +31,10 @@ both will discard uncommitted changes in your working directory. See "Reset, restore and revert" in linkgit:git[1] for the differences between the three commands. +Reverting a commit may result in a merge conflict. +See linkgit:gitmergeconflicts[7] (or `git help mergeconflicts`) +for a guide to handling merge conflicts. + OPTIONS ------- <commit>...::
@@ -162,6 +166,7 @@ include::config/revert.adoc[] SEE ALSO -------- linkgit:git-cherry-pick[1] +linkgit:gitmergeconflicts[7] GIT ---
Signature · 1 line
gitgitgadget
PATCH v3 5/6 doc: git-cherry-pick: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
Remove the discussion of merge conflicts and replace it with a link to the guide.
--- Documentation/git-cherry-pick.adoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
Documentation/git-cherry-pick.adoc +4 -4
@@ -19,8 +19,7 @@ Given one or more existing commits, apply the change each one introduces, recording a new commit for each. This requires your working tree to be clean (no modifications from the HEAD commit). -When it is not obvious how to apply a change, the following -happens: +When a merge conflict happens: 1. The current branch and `HEAD` pointer stay at the last commit successfully made.
@@ -36,8 +35,8 @@ happens: conflict markers `<<<<<<<` and `>>>>>>>`. 5. No other modifications are made. -See linkgit:git-merge[1] for some hints on resolving such -conflicts. +See linkgit:gitmergeconflicts[7] (or `git help mergeconflicts`) +for a guide to handling merge conflicts. OPTIONS -------
@@ -259,6 +258,7 @@ $ git cherry-pick -Xpatience topic^ <4> SEE ALSO -------- linkgit:git-revert[1] +linkgit:gitmergeconflicts[7] GIT ---
Signature · 1 line
gitgitgadget
Re: [PATCH v3 5/6] doc: git-cherry-pick: link to new merge conflicts guide
Quoted 4 lines · Julia Evans via GitGitGadget
From: Julia Evans <[email protected]>
Remove the discussion of merge conflicts and replace it with a link to the guide.
Nit: you don't really change the discussion anymore, so this commit message is inaccurate by now.
Patrick
PATCH v3 6/6 doc: git-pull: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
--- Documentation/git-pull.adoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Documentation/git-pull.adoc +2 -1
@@ -38,7 +38,8 @@ or `pull.ff` with your preferred behaviour. If there's a merge conflict during the merge or rebase that you don't want to handle, you can safely abort it with `git merge --abort` or -`git rebase --abort`. +`git rebase --abort`. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts. OPTIONS -------
Signature · 1 line
gitgitgadget
Quoted 8 lines · Julia Evans via GitGitGadget
Range-diff vs v2:
1:
ab0344f947! 1:7aa0ae7ec3doc: add new gitmergeconflicts man page
@@ Commit message
place, since it's a really nice example of a place Git has a consistent interface between similar commands.
Quoted 8 lines
+ Only discuss merge, rebase, cherry-pick, and revert for now even though
+ there are other ways that merge conflicts can happen because it's
+ awkward to talk aboutam,apply, andcheckout -m.
+Co-Authored-By Marie Claire LeBlanc Flanagan <[email protected]>- Reviewed-by: D. Ben Knoble <[email protected]>
- Reviewed-by: Patrick Steinhardt <[email protected]>
+ Helped-by: D. Ben Knoble <[email protected]>
Maybe this got lost in the shuffle, but I do prefer to use <[email protected]> for Git these days, thanks!
Quoted 4 lines
+ Helped-by: Patrick Steinhardt <[email protected]> + Signed-off-by: Julia Evans <[email protected]> + Signed-off-by: Marie Claire LeBlanc Flanagan <[email protected]>Signed-off-by Julia Evans <[email protected]>
I don't *think* we need your sign-off twice here, but maybe you intended to communicate something by this ordering? I confess I'm not sure what it would be ':D
Signature · 1 line
D. Ben Knoble
Quoted 19 lines · D. Ben Knoble
Quoted 8 lines · Julia Evans via GitGitGadget
Range-diff vs v2:
1:
ab0344f947! 1:7aa0ae7ec3doc: add new gitmergeconflicts man page
@@ Commit message
place, since it's a really nice example of a place Git has a consistent interface between similar commands.Quoted 8 lines
+ Only discuss merge, rebase, cherry-pick, and revert for now even though
+ there are other ways that merge conflicts can happen because it's
+ awkward to talk aboutam,apply, andcheckout -m.
+Co-Authored-By Marie Claire LeBlanc Flanagan <[email protected]>- Reviewed-by: D. Ben Knoble <[email protected]>
- Reviewed-by: Patrick Steinhardt <[email protected]>
+ Helped-by: D. Ben Knoble <[email protected]>
Quoted 2 lines
Maybe this got lost in the shuffle, but I do prefer to use <[email protected]> for Git these days, thanks!
Oops, I meant to fix that, thanks for pointing it out!
Quoted 8 lines
Quoted 4 lines
+ Helped-by: Patrick Steinhardt <[email protected]> + Signed-off-by: Julia Evans <[email protected]> + Signed-off-by: Marie Claire LeBlanc Flanagan <[email protected]>Signed-off-by Julia Evans <[email protected]>I don't *think* we need your sign-off twice here, but maybe you intended to communicate something by this ordering? I confess I'm not sure what it would be ':D
Oops yes that was a copy paste error. Obviously I'm having a hard time with my trailers as you can see :)
Quoted 15 lines · Julia Evans via GitGitGadget
Changed in v2:
* Explain what a merge conflict is (thanks to Junio & Ben)
* rewrite the "ours" vs "theirs" section (thanks to Patrick for the comments)
* add git log --merge (thanks to Ben)
* Leave most of the content of git cherry-pick as-is, to make this patch set smaller (thanks to Junio)
* remove the SYNOPSIS since hopefully that won't be required anymore by the time this is merged
* Fix a typo in git revert (s/reverted conflict/reverted commit/)
* 's/the the/the/' (thanks to Patrick)
* s/[doc] Thing/doc: thing/ in commit messages (thanks to Tuomas)'
* squash the commit fixing the linter error (thanks to Junio)
* list reviewers in Reviewed-by
I had some comments on diff3 in [1/6]; everything else looked good.
Thanks.
Quoted 1 line · Junio C Hamano
I had some comments on diff3 in [1/6]; everything else looked good.
Here is a restatement of my [1/6] review in a squashable patch form.
The second hunk arond l.77 replaces "code" with "lines", as not everybody using Git are writing program code, which is not what I mentioned earlier. There are parts that talk about programs and code, while other parts that talk about lines, so the mixture is already there, but I think this part does not have to be specific to code, but just applicable to anything that is line oriented.
The main part of this change is the updated diff3 example. It reveals that the situation was different from naive interpretation of an earlier (ambiguous) example showed. This should help readers appreciate the extra information diff3 format supplies.
Documentation/gitmergeconflicts.adoc | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-)
Documentation/gitmergeconflicts.adoc +20 -10
@@ -60,8 +60,9 @@ 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 added "cherry" and the other side -added "banana": +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 = [
@@ -76,8 +77,8 @@ FRUITS = [ ] ---- -The code from one side of the merge conflict is between `<<<<<<<` and -`=======`, and the code for the other side is between `=======` and +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.
@@ -121,8 +122,8 @@ FRUITS = [ ] ---- -Then you might edit that part of the code like this, -which includes the fruits from both sides of the conflict: +Then you might edit that part of the code like this, to take +all the fruits from both sides of the conflict: ---- FRUITS = [
@@ -208,15 +209,15 @@ 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. +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 added one fruit to the list. +mistake in "mango", and each removed one fruit from the list. ---- FRUITS = [
@@ -225,15 +226,24 @@ FRUITS = [ "cherry", "mango", ||||||| 1c22e48 + "banana", + "cherry", "mangoooo", ======= - "banana", "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
v4 cover Add new page on merge conflicts
In reply to Julia Evans via GitGitGadgetHandling merge conflicts is difficult, and currently Git's guidance on merge conflicts isn't giving users the information they need to navigate the process. As usual, the process I used to write this was to collect comments from Git users on the existing documentation, and then address those issues. I listed the specific issues we're aiming to solve in the first commit message in the series.
This patch series introduces a new manual page, gitmergeconflicts, which explains the process of explaining a merge conflict with examples. It also links to that new page from the commands which can cause merge conflicts, instead of trying to reexplain the process every time.
Changed in v2:
* Explain what a merge conflict is (thanks to Junio & Ben)
* rewrite the "ours" vs "theirs" section (thanks to Patrick for the comments)
* add git log --merge (thanks to Ben)
* Leave most of the content of git cherry-pick as-is, to make this patch set smaller (thanks to Junio)
* remove the SYNOPSIS since hopefully that won't be required anymore by the time this is merged
* Fix a typo in git revert (s/reverted conflict/reverted commit/)
* 's/the the/the/' (thanks to Patrick)
* s/[doc] Thing/doc: thing/ in commit messages (thanks to Tuomas)'
* squash the commit fixing the linter error (thanks to Junio)
* list reviewers in Reviewed-by
Changed in v3:
Thanks to all the comments from Junio.
* Add signoff from Marie
* In "For example, here's a merge conflict where both sides edited a list of", add a little more detail about how to interpret the merge conflict
* When we introduce a merge mention "semantic merge conflicts"
* Say "... and any other command that does a merge" when listing commands that can cause merge conflicts.
* Reviewed-by is not the right thing, use Helped-by
* Adjust phrasing in git revert and git cherry-pick man pages
* Reference the "ours" section in "git show :2:filename shows the "ours""
* "there's one file left with conflicts in it: fruits.py" isn't precise enough, instead say "the conflicts in fruits.py haven't been marked as resolved"
* Delete the explanation of zdiff3 and add a brief warning instead. Don't be too prescriptive, we should tell people what the issue is (ambiguity) instead of trying to impose our opinion.
* Explain ||||||| when we add diff3
* Fix example in "EXAMPLE OF RESOLVING A MERGE CONFLICT" to make it consistent with the other examples
* Replace "configuration option" with "configuration variable"
* Mention --skip instead of saying "the most common ways", which is ambiguous
* Add a pointer to the extended AUTO_MERGE sentence
Changed in v4:
changes to the content:
* use Junio's much better example for diff3
* clarify in the commit message why we're not mentioning git apply: to avoid dealing with patches (thanks to Junio)
* adjust the wording around "multi-step operation like a rebase" (thanks to Junio)
* Say "see git-config for more" in the description of zdiff3. Like Patrick said the explanation of zdiff3 is not really satisfiying, but I don't know how to write a satisfying explanation, and it's better to have a short and obviously unsatisfying explanation than a long unsatisfying one. Added a note in the commit message that perhaps this should be improved in the future. (from Patrick's comment)
changes cleaning things up:
* add periods at the ends of various sentences in an attempt to be more consistent (thanks to Junio & Patrick)
* Adjust the formatting around the [NOTE] to make the CI whitespace check pass
* Replace a couple of instances of "code" with "lines" (thanks to Junio)
* Fix Ben's email address (thanks to Ben)
* Remove the double signoff (thanks to Ben).
* Make the cherry-pick commit message more accurate (thanks to Patrick)
Thanks to Lobo, Adam Svahn, Louis Vanier, David Turner, Ben Zanin, Salih, and about 12 others who gave feedback on both the original git merge man page, as well as the proposed improvements.
Julia Evans (6):
doc: add new gitmergeconflicts man page
doc: git-merge: link to new merge conflicts guide
doc: git-rebase: link to new merge conflicts guide
doc: git-revert: link to new merge conflicts guide
doc: git-cherry-pick: link to new merge conflicts guide
doc: git-pull: link to new merge conflicts guide
.gitattributes | 1 + Documentation/Makefile | 1 + Documentation/git-cherry-pick.adoc | 8 +- Documentation/git-merge.adoc | 125 +--------- Documentation/git-pull.adoc | 3 +- Documentation/git-rebase.adoc | 13 +- Documentation/git-revert.adoc | 5 + Documentation/gitmergeconflicts.adoc | 339 +++++++++++++++++++++++++++ Documentation/meson.build | 1 + command-list.txt | 1 + 10 files changed, 366 insertions(+), 131 deletions(-) create mode 100644 Documentation/gitmergeconflicts.adoc
base-commit: 3bc0341126508f78f5869cbfc0005e987efdf0c7
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2237%2Fjvns%2Fmerge-conflicts-v4
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2237/jvns/merge-conflicts-v4
Pull-Request: https://github.com/gitgitgadget/git/pull/2237
Range-diff vs v3:
1: 7aa0ae7ec3 ! 1: 486a77dbd7 doc: add new gitmergeconflicts man page
@@ Commit message
- The process for resolving a merge conflict is only explained in the git merge man page, even though there are several other commands
- which can result in conflicts
+ which can result in conflicts.
- Sometimes we use "ours" and "theirs" to refer to the two sides of the merge conflicts and sometimes we use HEAD and MERGE_HEAD. It should be consistent. Also the terms "ours" and "theirs" are not explained. Similarly, it says "The part before the ======= is typically your side...", but doesn't explain what "typically" means.
- It introduces the merge format using an analogy to RCS, which very few
- Git users have ever used
+ Git users have ever used.
- In "The only clean-ups you need are to reset the index file to the HEAD commit to reverse 2. and to clean up working tree changes made by 2. and 3.", it's not clear to users what "2" and "3" are supposed
- to mean
+ to mean.
- It uses a cultural reference ("Conflict resolution is hard; let's go shopping.") which is confusing or unfamiliar to some people. I think it would be clearer for users to use a code example instead.
- - It doesn't explain the difference between diff3 and zdiff3
- - It sometimes uses the term "area" and sometimes uses the term "hunk"
+ - It doesn't explain the difference between diff3 and zdiff3.
+ - It sometimes uses the term "area" and sometimes uses the term "hunk".
Also document the unified --abort, --continue workflow in one place, since it's a really nice example of a place Git has a consistent interface between similar commands.
Only discuss merge, rebase, cherry-pick, and revert for now even though
- there are other ways that merge conflicts can happen because it's
- awkward to talk about am, apply, and checkout -m.
+ there are other ways that merge conflicts can happen to avoid getting
+ into the difference between applying a patch and doing a 3-way merge.
+
+ Things to potentially improve in future docs revisions:
+
+ - The explanation of zdiff3 is unsatisfying. It would be good if we
+ could have a clear example of a case where zdiff3 is helpful and a
+ case where it's harmful, and if we could give a better sense for
+ the reasons why users are actually choosing zdiff3 over diff3
+ (or the reverse) in real life.
- Helped-by: D. Ben Knoble <[email protected]>
+ Helped-by: D. Ben Knoble <[email protected]>
- Signed-off-by: Julia Evans <[email protected]>
@@ Documentation/gitmergeconflicts.adoc (new)
+ 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
++* 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?
+-------------------------
@@ Documentation/gitmergeconflicts.adoc (new)
+ 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
@@ Documentation/gitmergeconflicts.adoc (new)
+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 added "cherry" and the other side -+added "banana":
++fruits in different ways -- one side has "cherry" and the other side ++has "banana":
+
+----
+FRUITS = [
@@ Documentation/gitmergeconflicts.adoc (new)
+]
+----
+
-+The code from one side of the merge conflict is between <<<<<<< and -+=======, and the code for the other side is between ======= and ++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.
+
@@ Documentation/gitmergeconflicts.adoc (new)
+
+The process for resolving a merge conflict is:
+
-+1. Run git status to get a list of files with merge conflicts ++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
++ (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>>
@@ Documentation/gitmergeconflicts.adoc (new)
+* 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 ++* 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.
+
@@ Documentation/gitmergeconflicts.adoc (new)
+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 added one fruit to the list.
-+
+----
+FRUITS = [
+ "apple",
@@ Documentation/gitmergeconflicts.adoc (new)
+ "cherry",
+ "mango",
+||||||| 1c22e48
++ "banana",
++ "cherry",
+ "mangoooo",
+=======
+ "banana",
@@ Documentation/gitmergeconflicts.adoc (new)
+]
+----
+
++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.
-+================================
++shorter by making it more ambiguous. See linkgit:git-config[1] for more.
+
+[[ours]]
+"OURS" AND "THEIRS"
2: 8bdbd64ca3 = 2: 6862cb4f04 doc: git-merge: link to new merge conflicts guide 3: 34ba85fcad = 3: 2bd9850822 doc: git-rebase: link to new merge conflicts guide 4: 85e117b070 = 4: 53083b48a3 doc: git-revert: link to new merge conflicts guide 5: f99c99f955 ! 5: 92cfdf260c doc: git-cherry-pick: link to new merge conflicts guide
@@ Metadata
## Commit message ##
doc: git-cherry-pick: link to new merge conflicts guide
- Remove the discussion of merge conflicts and replace it with a link to
- the guide.
-
## Documentation/git-cherry-pick.adoc ##
6: 7831b77178 = 6: bbbf44aff1 doc: git-pull: link to new merge conflicts guide
Signature · 1 line
gitgitgadget
PATCH v4 1/6 doc: add new gitmergeconflicts man page
From: Julia Evans <[email protected]>
Introduce a new page, gitmergeconflicts, that explains the process of handling a merge conflict in a way that addresses the following issues, which came from feedback from Git users on the current explanation of merge conflicts in the git merge man page:
- The process for resolving a merge conflict is only explained in the git merge man page, even though there are several other commands which can result in conflicts.
- Sometimes we use "ours" and "theirs" to refer to the two sides of the merge conflicts and sometimes we use HEAD and MERGE_HEAD. It should be consistent. Also the terms "ours" and "theirs" are not explained. Similarly, it says "The part before the ======= is typically your side...", but doesn't explain what "typically" means.
- It introduces the merge format using an analogy to RCS, which very few Git users have ever used.
- In "The only clean-ups you need are to reset the index file to the HEAD commit to reverse 2. and to clean up working tree changes made by 2. and 3.", it's not clear to users what "2" and "3" are supposed to mean.
- It uses a cultural reference ("Conflict resolution is hard; let's go shopping.") which is confusing or unfamiliar to some people. I think it would be clearer for users to use a code example instead.
- It doesn't explain the difference between diff3 and zdiff3.
- It sometimes uses the term "area" and sometimes uses the term "hunk".
Also document the unified --abort, --continue workflow in one place, since it's a really nice example of a place Git has a consistent interface between similar commands.
Only discuss merge, rebase, cherry-pick, and revert for now even though there are other ways that merge conflicts can happen to avoid getting into the difference between applying a patch and doing a 3-way merge.
Things to potentially improve in future docs revisions:
- The explanation of zdiff3 is unsatisfying. It would be good if we could have a clear example of a case where zdiff3 is helpful and a case where it's harmful, and if we could give a better sense for the reasons why users are actually choosing zdiff3 over diff3 (or the reverse) in real life.
--- .gitattributes | 1 + Documentation/Makefile | 1 + Documentation/gitmergeconflicts.adoc | 339 +++++++++++++++++++++++++++ Documentation/meson.build | 1 + command-list.txt | 1 + 5 files changed, 343 insertions(+) create mode 100644 Documentation/gitmergeconflicts.adoc
.gitattributes +1 -0
@@ -14,6 +14,7 @@ CODE_OF_CONDUCT.md -whitespace /t/oid-info/* text eol=lf /Documentation/git-merge.adoc conflict-marker-size=32 /Documentation/git-merge-file.adoc conflict-marker-size=32 +/Documentation/gitmergeconflicts.adoc conflict-marker-size=32 /Documentation/gitk.adoc conflict-marker-size=32 /Documentation/user-manual.adoc conflict-marker-size=32 /t/t????-*.sh conflict-marker-size=32
Documentation/Makefile +1 -0
@@ -58,6 +58,7 @@ MAN7_TXT += gitdiffcore.adoc MAN7_TXT += giteveryday.adoc MAN7_TXT += gitfaq.adoc MAN7_TXT += gitglossary.adoc +MAN7_TXT += gitmergeconflicts.adoc MAN7_TXT += gitpacking.adoc MAN7_TXT += gitnamespaces.adoc MAN7_TXT += gitremote-helpers.adoc
Documentation/gitmergeconflicts.adoc new file +339 -0
339 lines not on this page · raw message
Documentation/meson.build +1 -0
@@ -202,6 +202,7 @@ manpages = { 'gitfaq.adoc' : 7, 'gitglossary.adoc' : 7, 'gitpacking.adoc' : 7, + 'gitmergeconflicts.adoc' : 7, 'gitnamespaces.adoc' : 7, 'gitremote-helpers.adoc' : 7, 'gitrevisions.adoc' : 7,
command-list.txt +1 -0
@@ -232,6 +232,7 @@ githooks userinterfaces gitignore userinterfaces gitk mainporcelain gitmailmap userinterfaces +gitmergeconflicts guide gitmodules userinterfaces gitnamespaces guide gitprotocol-capabilities developerinterfaces
Signature · 1 line
gitgitgadget
Re: [PATCH v4 1/6] doc: add new gitmergeconflicts man page
Quoted 7 lines · Julia Evans via GitGitGadget
Things to potentially improve in future docs revisions:
- The explanation of zdiff3 is unsatisfying. It would be good if we could have a clear example of a case where zdiff3 is helpful and a case where it's harmful, and if we could give a better sense for the reasons why users are actually choosing zdiff3 over diff3 (or the reverse) in real life.
Is this a stale comment? I think you reduced this to just a side note that says shoter but ambiguous, which is probably good enough.
Quoted 13 lines
+[[diff3]]
Documentation/gitmergeconflicts.adoc new file +12
-0+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.
Documentation/gitmergeconflicts.adoc line 224
Quoted 10 lines
Documentation/gitmergeconflicts.adoc new file +10
-0+ +---- +FRUITS = [ + "apple", +<<<<<<< HEAD + "cherry", + "mango", +||||||| 1c22e48 + "banana", + "cherry",
These two should be indented with spaces the same way as all the other lines in this list.
Documentation/gitmergeconflicts.adoc line 235
Quoted 11 lines
Documentation/gitmergeconflicts.adoc new file +11
-0+ "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.
", and each removed one from the list", I think.
Documentation/gitmergeconflicts.adoc line 238
Quoted 3 lines
Documentation/gitmergeconflicts.adoc new file +3
-0+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:
The reason why removal becomes the correct resolution is not just one side removed, but the fact that the other side did not touch what was removed by one side. The "indifference by the other" is what makes one's removal the preferred action by the semantics of 3-way merge.
So, let's rewrite the reason a bit more tightly.
since one side removed banana while the other side did not touch, and the same happend to cherry, it makes sense to remove both from the list ...
or somethig like that.
Other than that, I did not see anything questionable in the 6 patches.
Re: [PATCH v4 1/6] doc: add new gitmergeconflicts man page
Quoted 10 lines · Junio C Hamano
Quoted 7 lines · Julia Evans via GitGitGadget
Things to potentially improve in future docs revisions:
- The explanation of zdiff3 is unsatisfying. It would be good if we could have a clear example of a case where zdiff3 is helpful and a case where it's harmful, and if we could give a better sense for the reasons why users are actually choosing zdiff3 over diff3 (or the reverse) in real life.
Quoted 3 lines
Is this a stale comment? I think you reduced this to just a side note that says
shoter but ambiguous, which is probably good enough.
It's not, but I'll delete it anyway because I don't think it's adding much.
Quoted 18 lines
Quoted 18 lines
+[[diff3]]
Documentation/gitmergeconflicts.adoc new file +17
-0+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
Quoted 8 lines
Documentation/gitmergeconflicts.adoc line 224
Quoted 5 lines
Documentation/gitmergeconflicts.adoc new file +5
-0+ "cherry", + "mango", +||||||| 1c22e48 + "banana", + "cherry",These two should be indented with spaces the same way as all the other lines in this list.
Will fix, thanks.
Quoted 5 lines
Quoted 5 lines
Documentation/gitmergeconflicts.adoc new file +5
-0+ "mangoooo", +======= + "banana", + "mango", +>>>>>>> add-fruit
Quoted 8 lines
Documentation/gitmergeconflicts.adoc line 235
Quoted 6 lines
Documentation/gitmergeconflicts.adoc new file +6
-0+ "orange", +] +---- + +With this view, you can see that both sides fixed a spelling +mistake in "mango", and each removed one fruit to the list.", and each removed one from the list", I think.
Thanks, will fix.
Quoted 10 lines
Documentation/gitmergeconflicts.adoc line 238
Quoted 3 lines
Documentation/gitmergeconflicts.adoc new file +3
-0+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:The reason why removal becomes the correct resolution is not just one side removed, but the fact that the other side did not touch what was removed by one side. The "indifference by the other" is what makes one's removal the preferred action by the semantics of 3-way merge.
Quoted 5 lines
So, let's rewrite the reason a bit more tightly.
since one side removed
bananawhile the other side did not touch, and the same happend tocherry, it makes sense to remove both from the list ...
I tried to edit this (like below) but only ended up removing "probably". But "probably" was there for a reason, since this is a made up example and in the real world you would really need to apply some judgement to know what the right thing to do is. I left it as is.
-side removed banana and one side removed cherry, it would probably -make sense to remove both from the list, like this:
+side removed banana and one side removed cherry, it makes sense +to remove both from the list, like this:
Quoted 4 lines
or somethig like that.
Other than that, I did not see anything questionable in the 6 patches.
Re: [PATCH v4 1/6] doc: add new gitmergeconflicts man page
Quoted 11 lines · Julia Evans
Quoted 5 lines
So, let's rewrite the reason a bit more tightly.
since one side removed
bananawhile the other side did not touch, and the same happend tocherry, it makes sense to remove both from the list ...I tried to edit this (like below) but only ended up removing "probably". But "probably" was there for a reason, since this is a made up example and in the real world you would really need to apply some judgement to know what the right thing to do is. I left it as is.
Review
Quoted 4 lines
(quoted diff) +2
-2-side removed `banana` and one side removed `cherry`, it would probably -make sense to remove both from the list, like this: +side removed `banana` and one side removed `cherry`, it makes sense +to remove both from the list, like this:
Are we talking past each other? I did not mean "probably" was not tight enough, and probably is probably a good thing to have there.
The value I wanted to bring on the table was to point out that the changes are not just "one side did something", but "one side did something where the other side had no opinion on (hence it didn't do anything)". It is the basis of how 3-way merge works and helps to resolve the example for removal of both.
Re: [PATCH v4 1/6] doc: add new gitmergeconflicts man page
Quoted 21 lines · Junio C Hamano
Quoted 11 lines · Julia Evans
Quoted 5 lines
So, let's rewrite the reason a bit more tightly.
since one side removed
bananawhile the other side did not touch, and the same happend tocherry, it makes sense to remove both from the list ...I tried to edit this (like below) but only ended up removing "probably". But "probably" was there for a reason, since this is a made up example and in the real world you would really need to apply some judgement to know what the right thing to do is. I left it as is.
Review
Quoted 4 lines
(quoted diff) +2
-2-side removed `banana` and one side removed `cherry`, it would probably -make sense to remove both from the list, like this: +side removed `banana` and one side removed `cherry`, it makes sense +to remove both from the list, like this:Are we talking past each other? I did not mean "probably" was not tight enough, and probably is probably a good thing to have there.
Quoted 5 lines
The value I wanted to bring on the table was to point out that the changes are not just "one side did something", but "one side did something where the other side had no opinion on (hence it didn't do anything)". It is the basis of how 3-way merge works and helps to resolve the example for removal of both.
Oh, I see. This is such a simple example that IMO trying to explain in more detail exactly "why" the resolution is correct risks confusing people. My goal with saying "one side removed 'banana'" is just to give an example of how to read what the merge conflict above is saying, since the syntax might be new to people.
Re: [PATCH v4 1/6] doc: add new gitmergeconflicts man page
Quoted 11 lines · Julia Evans
Quoted 5 lines
The value I wanted to bring on the table was to point out that the changes are not just "one side did something", but "one side did something where the other side had no opinion on (hence it didn't do anything)". It is the basis of how 3-way merge works and helps to resolve the example for removal of both.
Oh, I see. This is such a simple example that IMO trying to explain in more detail exactly "why" the resolution is correct risks confusing people. My goal with saying "one side removed 'banana'" is just to give an example of how to read what the merge conflict above is saying, since the syntax might be new to people.
OK. Other than that, I do not think anybody saw an issue in this iteration, and I suspect that we are reaching the point of diminishing returns. Let me mark the topic as ready for 'next'.
THanks.
PATCH v4 2/6 doc: git-merge: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
All of the info about merge conflicts has been moved to the new guide
--- Documentation/git-merge.adoc | 125 +---------------------------------- 1 file changed, 3 insertions(+), 122 deletions(-)
Documentation/git-merge.adoc +3 -122
@@ -49,7 +49,8 @@ a log message from the user describing the changes. Before the operation, A merge stops if there's a conflict that cannot be resolved automatically or if `--no-commit` was provided when initiating the merge. At that point you can run `git merge --abort` or `git merge ---continue`. +--continue`. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts. `git merge --abort` will abort the merge process and try to reconstruct the pre-merge state. However, if there were uncommitted changes when the
@@ -231,127 +232,6 @@ git merge v1.2.3^0 git merge --ff-only v1.2.3 ---- -HOW CONFLICTS ARE PRESENTED ---------------------------- - -During a merge, the working tree files are updated to reflect the result -of the merge. Among the changes made to the common ancestor's version, -non-overlapping ones (that is, you changed an area of the file while the -other side left that area intact, or vice versa) are incorporated in the -final result verbatim. When both sides made changes to the same area, -however, Git cannot randomly pick one side over the other, and asks you to -resolve it by leaving what both sides did to that area. - -By default, Git uses the same style as the one used by the "merge" program -from the RCS suite to present such a conflicted hunk, like this: - ------------- -Here are lines that are either unchanged from the common -ancestor, or cleanly resolved because only one side changed, -or cleanly resolved because both sides changed the same way. -<<<<<<< yours:sample.txt -Conflict resolution is hard; -let's go shopping. -======= -Git makes conflict resolution easy. ->>>>>>> theirs:sample.txt -And here is another line that is cleanly resolved or unmodified. ------------- - -The area where a pair of conflicting changes happened is marked with markers -+<<<<<<<+, `=======`, and +>>>>>>>+. The part before the `=======` -is typically your side, and the part afterwards is typically their side. - -The default format does not show what the original said in the conflicting -area. You cannot tell how many lines are deleted and replaced with -Barbie's remark on your side. The only thing you can tell is that your -side wants to say it is hard and you'd prefer to go shopping, while the -other side wants to claim it is easy. - -An alternative style can be used by setting the `merge.conflictStyle` -configuration variable to either `diff3` or `zdiff3`. In `diff3` -style, the above conflict may look like this: - ------------- -Here are lines that are either unchanged from the common -ancestor, or cleanly resolved because only one side changed, -<<<<<<< yours:sample.txt -or cleanly resolved because both sides changed the same way. -Conflict resolution is hard; -let's go shopping. -||||||| base:sample.txt -or cleanly resolved because both sides changed identically. -Conflict resolution is hard. -======= -or cleanly resolved because both sides changed the same way. -Git makes conflict resolution easy. ->>>>>>> theirs:sample.txt -And here is another line that is cleanly resolved or unmodified. ------------- - -while in `zdiff3` style, it may look like this: - ------------- -Here are lines that are either unchanged from the common -ancestor, or cleanly resolved because only one side changed, -or cleanly resolved because both sides changed the same way. -<<<<<<< yours:sample.txt -Conflict resolution is hard; -let's go shopping. -||||||| base:sample.txt -or cleanly resolved because both sides changed identically. -Conflict resolution is hard. -======= -Git makes conflict resolution easy. ->>>>>>> theirs:sample.txt -And here is another line that is cleanly resolved or unmodified. ------------- - -In addition to the +<<<<<<<+, `=======`, and +>>>>>>>+ markers, it uses -another +|||||||+ marker that is followed by the original text. You can -tell that the original just stated a fact, and your side simply gave in to -that statement and gave up, while the other side tried to have a more -positive attitude. You can sometimes come up with a better resolution by -viewing the original. - - -HOW TO RESOLVE CONFLICTS ------------------------- - -After seeing a conflict, you can do two things: - - * Decide not to merge. The only clean-ups you need are to reset - the index file to the `HEAD` commit to reverse 2. and to clean - up working tree changes made by 2. and 3.; `git merge --abort` - can be used for this. - - * Resolve the conflicts. Git will mark the conflicts in - the working tree. Edit the files into shape and - `git add` them to the index. Use `git commit` or - `git merge --continue` to seal the deal. The latter command - checks whether there is a (interrupted) merge in progress - before calling `git commit`. - -You can work through the conflict with a number of tools: - - * Use a mergetool. `git mergetool` to launch a graphical - mergetool which will work through the merge with you. - - * Look at the diffs. `git diff` will show a three-way diff, - highlighting changes from both the `HEAD` and `MERGE_HEAD` - versions. `git diff AUTO_MERGE` will show what changes you've - made so far to resolve textual conflicts. - - * Look at the diffs from each branch. `git log --merge -p <path>` - will show diffs first for the `HEAD` version and then the - `MERGE_HEAD` version. - - * Look at the originals. `git show :1:filename` shows the - common ancestor, `git show :2:filename` shows the `HEAD` - version, and `git show :3:filename` shows the `MERGE_HEAD` - version. - - EXAMPLES --------
@@ -406,6 +286,7 @@ linkgit:git-reset[1], linkgit:git-diff[1], linkgit:git-ls-files[1], linkgit:git-add[1], linkgit:git-rm[1], linkgit:git-mergetool[1] +linkgit:gitmergeconflicts[7] GIT ---
Signature · 1 line
gitgitgadget
PATCH v4 3/6 doc: git-rebase: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
Remove some of the detail about how to handle a merge conflict, since it's explained in detail in the new guide, and there probably isn't enough detail anyway.
Leave the steps since rebase is special and has a --skip option which the other commands which cause merge conflicts don't have.
--- Documentation/git-rebase.adoc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
Documentation/git-rebase.adoc +9 -4
@@ -46,10 +46,7 @@ If there is a merge conflict during this process, `git rebase` will stop at the first problematic commit and leave conflict markers. If this happens, you can do one of these things: -1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<) - and make edits to resolve the conflict. For each file you edit, you need to - tell Git that the conflict has been resolved. You can mark the conflict as - resolved with `git add <filename>`. After resolving all of the conflicts, +1. Resolve the conflict. After resolving all of the conflicts, you can continue the rebasing process with git rebase --continue
@@ -62,6 +59,9 @@ one of these things: git rebase --skip +See linkgit:gitmergeconflicts[7] (or `git help mergeconflicts`) +for a full guide to handling merge conflicts. + If you don't specify an `<upstream>` to rebase onto, the upstream configured in `branch.<name>.remote` and `branch.<name>.merge` options will be used (see linkgit:git-config[1] for details) and the `--fork-point` option is
@@ -1284,6 +1284,11 @@ include::includes/cmd-config-section-all.adoc[] include::config/rebase.adoc[] include::config/sequencer.adoc[] +SEE ALSO +-------- + +linkgit:gitmergeconflicts[7] + GIT --- Part of the linkgit:git[1] suite
Signature · 1 line
gitgitgadget
PATCH v4 4/6 doc: git-revert: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
--- Documentation/git-revert.adoc | 5 +++++ 1 file changed, 5 insertions(+)
Documentation/git-revert.adoc +5 -0
@@ -31,6 +31,10 @@ both will discard uncommitted changes in your working directory. See "Reset, restore and revert" in linkgit:git[1] for the differences between the three commands. +Reverting a commit may result in a merge conflict. +See linkgit:gitmergeconflicts[7] (or `git help mergeconflicts`) +for a guide to handling merge conflicts. + OPTIONS ------- <commit>...::
@@ -162,6 +166,7 @@ include::config/revert.adoc[] SEE ALSO -------- linkgit:git-cherry-pick[1] +linkgit:gitmergeconflicts[7] GIT ---
Signature · 1 line
gitgitgadget
PATCH v4 5/6 doc: git-cherry-pick: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
--- Documentation/git-cherry-pick.adoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
Documentation/git-cherry-pick.adoc +4 -4
@@ -19,8 +19,7 @@ Given one or more existing commits, apply the change each one introduces, recording a new commit for each. This requires your working tree to be clean (no modifications from the HEAD commit). -When it is not obvious how to apply a change, the following -happens: +When a merge conflict happens: 1. The current branch and `HEAD` pointer stay at the last commit successfully made.
@@ -36,8 +35,8 @@ happens: conflict markers `<<<<<<<` and `>>>>>>>`. 5. No other modifications are made. -See linkgit:git-merge[1] for some hints on resolving such -conflicts. +See linkgit:gitmergeconflicts[7] (or `git help mergeconflicts`) +for a guide to handling merge conflicts. OPTIONS -------
@@ -259,6 +258,7 @@ $ git cherry-pick -Xpatience topic^ <4> SEE ALSO -------- linkgit:git-revert[1] +linkgit:gitmergeconflicts[7] GIT ---
Signature · 1 line
gitgitgadget
PATCH v4 6/6 doc: git-pull: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
--- Documentation/git-pull.adoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Documentation/git-pull.adoc +2 -1
@@ -38,7 +38,8 @@ or `pull.ff` with your preferred behaviour. If there's a merge conflict during the merge or rebase that you don't want to handle, you can safely abort it with `git merge --abort` or -`git rebase --abort`. +`git rebase --abort`. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts. OPTIONS -------
Signature · 1 line
gitgitgadget
Quoted 84 lines · Julia Evans via GitGitGadget
Handling merge conflicts is difficult, and currently Git's guidance on merge conflicts isn't giving users the information they need to navigate the process. As usual, the process I used to write this was to collect comments from Git users on the existing documentation, and then address those issues. I listed the specific issues we're aiming to solve in the first commit message in the series.
This patch series introduces a new manual page, gitmergeconflicts, which explains the process of explaining a merge conflict with examples. It also links to that new page from the commands which can cause merge conflicts, instead of trying to reexplain the process every time.
Changed in v2:
* Explain what a merge conflict is (thanks to Junio & Ben)
* rewrite the "ours" vs "theirs" section (thanks to Patrick for the comments)
* add git log --merge (thanks to Ben)
* Leave most of the content of git cherry-pick as-is, to make this patch set smaller (thanks to Junio)
* remove the SYNOPSIS since hopefully that won't be required anymore by the time this is merged
* Fix a typo in git revert (s/reverted conflict/reverted commit/)
* 's/the the/the/' (thanks to Patrick)
* s/[doc] Thing/doc: thing/ in commit messages (thanks to Tuomas)'
* squash the commit fixing the linter error (thanks to Junio)
* list reviewers in Reviewed-byChanged in v3:
Thanks to all the comments from Junio.
* Add signoff from Marie
* In "For example, here's a merge conflict where both sides edited a list of", add a little more detail about how to interpret the merge conflict
* When we introduce a merge mention "semantic merge conflicts"
* Say "... and any other command that does a merge" when listing commands that can cause merge conflicts.
* Reviewed-by is not the right thing, use Helped-by
* Adjust phrasing in git revert and git cherry-pick man pages
* Reference the "ours" section in "git show :2:filename shows the "ours""
* "there's one file left with conflicts in it:fruits.py" isn't precise enough, instead say "the conflicts infruits.pyhaven't been marked as resolved"
* Delete the explanation of zdiff3 and add a brief warning instead. Don't be too prescriptive, we should tell people what the issue is (ambiguity) instead of trying to impose our opinion.
* Explain ||||||| when we add diff3
* Fix example in "EXAMPLE OF RESOLVING A MERGE CONFLICT" to make it consistent with the other examples
* Replace "configuration option" with "configuration variable"
* Mention --skip instead of saying "the most common ways", which is ambiguous
* Add a pointer to the extendedAUTO_MERGEsentenceChanged in v4:
changes to the content:
* use Junio's much better example for diff3
* clarify in the commit message why we're not mentioning git apply: to avoid dealing with patches (thanks to Junio)
* adjust the wording around "multi-step operation like a rebase" (thanks to Junio)
* Say "see git-config for more" in the description of zdiff3. Like Patrick said the explanation of zdiff3 is not really satisfiying, but I don't know how to write a satisfying explanation, and it's better to have a short and obviously unsatisfying explanation than a long unsatisfying one. Added a note in the commit message that perhaps this should be improved in the future. (from Patrick's comment)changes cleaning things up:
* add periods at the ends of various sentences in an attempt to be more consistent (thanks to Junio & Patrick)
* Adjust the formatting around the [NOTE] to make the CI whitespace check pass
* Replace a couple of instances of "code" with "lines" (thanks to Junio)
* Fix Ben's email address (thanks to Ben)
* Remove the double signoff (thanks to Ben).
* Make the cherry-pick commit message more accurate (thanks to Patrick)
Quoted 3 lines
Thanks to Lobo, Adam Svahn, Louis Vanier, David Turner, Ben Zanin, Salih, and about 12 others who gave feedback on both the original git merge man page, as well as the proposed improvements.
I’m happy with this version based on the range-diff, and I suspect we are reaching the point of diminishing returns.
Quoted 8 lines · Julia Evans via GitGitGadget
@@
Documentation/gitmergeconflicts.adoc(new)
+ "cherry",
+ "mango",
+||||||| 1c22e48
++ "banana",
++ "cherry",
+ "mangoooo",
+=======
Is it intended to use different indentation style for the entries to be removed from the list, or is it a simple mistake?
Quoted 7 lines
+ "banana",
@@Documentation/gitmergeconflicts.adoc(new)
+]
+----
+
++With this view, you can see that both sides fixed a spelling ++mistake in "mango", and each removed one fruit to the list.
"removed one fruit *from* the list", no?
I'll block time to read the whole thing over later today. Thanks.
Quoted 6 lines · Julia Evans via GitGitGadget
Handling merge conflicts is difficult, and currently Git's guidance on merge conflicts isn't giving users the information they need to navigate the process. As usual, the process I used to write this was to collect comments from Git users on the existing documentation, and then address those issues. I listed the specific issues we're aiming to solve in the first commit message in the series.
$ make check-docs
GIT_VERSION=2.56.0.rc2.6.gf97f562a2c
make -C Documentation lint-docs
make[1]: Entering directory '/home/gitster/w/git/Documentation'
LINT MAN SEC gitmergeconflicts.adoc
gitmergeconflicts.adoc:339: has no required 'SYNOPSIS' section!Quoted 9 lines · Junio C Hamano
Quoted 6 lines · Julia Evans via GitGitGadget
Handling merge conflicts is difficult, and currently Git's guidance on merge conflicts isn't giving users the information they need to navigate the process. As usual, the process I used to write this was to collect comments from Git users on the existing documentation, and then address those issues. I listed the specific issues we're aiming to solve in the first commit message in the series.
Quoted 6 lines
$ make check-docs
GIT_VERSION=2.56.0.rc2.6.gf97f562a2c
make -C Documentation lint-docs
make[1]: Entering directory '/home/gitster/w/git/Documentation'
LINT MAN SEC gitmergeconflicts.adoc
gitmergeconflicts.adoc:339: has no required 'SYNOPSIS' section!Ah, nevermind. Merge to 'seen' is (and has been) taking care of this already.
v5 cover Add new page on merge conflicts
In reply to Julia Evans via GitGitGadgetHandling merge conflicts is difficult, and currently Git's guidance on merge conflicts isn't giving users the information they need to navigate the process. As usual, the process I used to write this was to collect comments from Git users on the existing documentation, and then address those issues. I listed the specific issues we're aiming to solve in the first commit message in the series.
This patch series introduces a new manual page, gitmergeconflicts, which explains the process of explaining a merge conflict with examples. It also links to that new page from the commands which can cause merge conflicts, instead of trying to reexplain the process every time.
Changed in v2:
* Explain what a merge conflict is (thanks to Junio & Ben)
* rewrite the "ours" vs "theirs" section (thanks to Patrick for the comments)
* add git log --merge (thanks to Ben)
* Leave most of the content of git cherry-pick as-is, to make this patch set smaller (thanks to Junio)
* remove the SYNOPSIS since hopefully that won't be required anymore by the time this is merged
* Fix a typo in git revert (s/reverted conflict/reverted commit/)
* 's/the the/the/' (thanks to Patrick)
* s/[doc] Thing/doc: thing/ in commit messages (thanks to Tuomas)'
* squash the commit fixing the linter error (thanks to Junio)
* list reviewers in Reviewed-by
Changed in v3:
Thanks to all the comments from Junio.
* Add signoff from Marie
* In "For example, here's a merge conflict where both sides edited a list of", add a little more detail about how to interpret the merge conflict
* When we introduce a merge mention "semantic merge conflicts"
* Say "... and any other command that does a merge" when listing commands that can cause merge conflicts.
* Reviewed-by is not the right thing, use Helped-by
* Adjust phrasing in git revert and git cherry-pick man pages
* Reference the "ours" section in "git show :2:filename shows the "ours""
* "there's one file left with conflicts in it: fruits.py" isn't precise enough, instead say "the conflicts in fruits.py haven't been marked as resolved"
* Delete the explanation of zdiff3 and add a brief warning instead. Don't be too prescriptive, we should tell people what the issue is (ambiguity) instead of trying to impose our opinion.
* Explain ||||||| when we add diff3
* Fix example in "EXAMPLE OF RESOLVING A MERGE CONFLICT" to make it consistent with the other examples
* Replace "configuration option" with "configuration variable"
* Mention --skip instead of saying "the most common ways", which is ambiguous
* Add a pointer to the extended AUTO_MERGE sentence
Changed in v4:
changes to the content:
* use Junio's much better example for diff3
* clarify in the commit message why we're not mentioning git apply: to avoid dealing with patches (thanks to Junio)
* adjust the wording around "multi-step operation like a rebase" (thanks to Junio)
* Say "see git-config for more" in the description of zdiff3. Like Patrick said the explanation of zdiff3 is not really satisfiying, but I don't know how to write a satisfying explanation, and it's better to have a short and obviously unsatisfying explanation than a long unsatisfying one. Added a note in the commit message that perhaps this should be improved in the future. (from Patrick's comment)
changes cleaning things up:
* add periods at the ends of various sentences in an attempt to be more consistent (thanks to Junio & Patrick)
* Adjust the formatting around the [NOTE] to make the CI whitespace check pass
* Replace a couple of instances of "code" with "lines" (thanks to Junio)
* Fix Ben's email address (thanks to Ben)
* Remove the double signoff (thanks to Ben).
* Make the cherry-pick commit message more accurate (thanks to Patrick)
Thanks to Lobo, Adam Svahn, Louis Vanier, David Turner, Ben Zanin, Salih, and about 12 others who gave feedback on both the original git merge man page, as well as the proposed improvements.
Julia Evans (6):
doc: add new gitmergeconflicts man page
doc: git-merge: link to new merge conflicts guide
doc: git-rebase: link to new merge conflicts guide
doc: git-revert: link to new merge conflicts guide
doc: git-cherry-pick: link to new merge conflicts guide
doc: git-pull: link to new merge conflicts guide
.gitattributes | 1 + Documentation/Makefile | 1 + Documentation/git-cherry-pick.adoc | 8 +- Documentation/git-merge.adoc | 125 +--------- Documentation/git-pull.adoc | 3 +- Documentation/git-rebase.adoc | 13 +- Documentation/git-revert.adoc | 5 + Documentation/gitmergeconflicts.adoc | 339 +++++++++++++++++++++++++++ Documentation/meson.build | 1 + command-list.txt | 1 + 10 files changed, 366 insertions(+), 131 deletions(-) create mode 100644 Documentation/gitmergeconflicts.adoc
base-commit: 3bc0341126508f78f5869cbfc0005e987efdf0c7
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2237%2Fjvns%2Fmerge-conflicts-v5
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2237/jvns/merge-conflicts-v5
Pull-Request: https://github.com/gitgitgadget/git/pull/2237
Range-diff vs v4:
1: 486a77dbd7 ! 1: 8b526e2bd7 doc: add new gitmergeconflicts man page
@@ Commit message
there are other ways that merge conflicts can happen to avoid getting into the difference between applying a patch and doing a 3-way merge.
- Things to potentially improve in future docs revisions:
-
- - The explanation of zdiff3 is unsatisfying. It would be good if we
- could have a clear example of a case where zdiff3 is helpful and a
- case where it's harmful, and if we could give a better sense for
- the reasons why users are actually choosing zdiff3 over diff3
- (or the reverse) in real life.
-
@@ Documentation/gitmergeconflicts.adoc (new)
+ "cherry",
+ "mango",
+||||||| 1c22e48
-+ "banana",
-+ "cherry",
++ "banana",
++ "cherry",
+ "mangoooo",
+=======
+ "banana",
@@ Documentation/gitmergeconflicts.adoc (new)
+----
+
+With this view, you can see that both sides fixed a spelling
-+mistake in "mango", and each removed one fruit to the list. ++mistake in "mango", and each removed one fruit from 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:
2: 6862cb4f04 = 2: 3dc763a2a2 doc: git-merge: link to new merge conflicts guide 3: 2bd9850822 = 3: 02351af1b5 doc: git-rebase: link to new merge conflicts guide 4: 53083b48a3 = 4: 10f8947b68 doc: git-revert: link to new merge conflicts guide 5: 92cfdf260c = 5: e1fe1c4aa3 doc: git-cherry-pick: link to new merge conflicts guide 6: bbbf44aff1 = 6: 4f434f5acd doc: git-pull: link to new merge conflicts guide
Signature · 1 line
gitgitgadget
PATCH v5 1/6 doc: add new gitmergeconflicts man page
From: Julia Evans <[email protected]>
Introduce a new page, gitmergeconflicts, that explains the process of handling a merge conflict in a way that addresses the following issues, which came from feedback from Git users on the current explanation of merge conflicts in the git merge man page:
- The process for resolving a merge conflict is only explained in the git merge man page, even though there are several other commands which can result in conflicts.
- Sometimes we use "ours" and "theirs" to refer to the two sides of the merge conflicts and sometimes we use HEAD and MERGE_HEAD. It should be consistent. Also the terms "ours" and "theirs" are not explained. Similarly, it says "The part before the ======= is typically your side...", but doesn't explain what "typically" means.
- It introduces the merge format using an analogy to RCS, which very few Git users have ever used.
- In "The only clean-ups you need are to reset the index file to the HEAD commit to reverse 2. and to clean up working tree changes made by 2. and 3.", it's not clear to users what "2" and "3" are supposed to mean.
- It uses a cultural reference ("Conflict resolution is hard; let's go shopping.") which is confusing or unfamiliar to some people. I think it would be clearer for users to use a code example instead.
- It doesn't explain the difference between diff3 and zdiff3.
- It sometimes uses the term "area" and sometimes uses the term "hunk".
Also document the unified --abort, --continue workflow in one place, since it's a really nice example of a place Git has a consistent interface between similar commands.
Only discuss merge, rebase, cherry-pick, and revert for now even though there are other ways that merge conflicts can happen to avoid getting into the difference between applying a patch and doing a 3-way merge.
--- .gitattributes | 1 + Documentation/Makefile | 1 + Documentation/gitmergeconflicts.adoc | 339 +++++++++++++++++++++++++++ Documentation/meson.build | 1 + command-list.txt | 1 + 5 files changed, 343 insertions(+) create mode 100644 Documentation/gitmergeconflicts.adoc
.gitattributes +1 -0
@@ -14,6 +14,7 @@ CODE_OF_CONDUCT.md -whitespace /t/oid-info/* text eol=lf /Documentation/git-merge.adoc conflict-marker-size=32 /Documentation/git-merge-file.adoc conflict-marker-size=32 +/Documentation/gitmergeconflicts.adoc conflict-marker-size=32 /Documentation/gitk.adoc conflict-marker-size=32 /Documentation/user-manual.adoc conflict-marker-size=32 /t/t????-*.sh conflict-marker-size=32
Documentation/Makefile +1 -0
@@ -58,6 +58,7 @@ MAN7_TXT += gitdiffcore.adoc MAN7_TXT += giteveryday.adoc MAN7_TXT += gitfaq.adoc MAN7_TXT += gitglossary.adoc +MAN7_TXT += gitmergeconflicts.adoc MAN7_TXT += gitpacking.adoc MAN7_TXT += gitnamespaces.adoc MAN7_TXT += gitremote-helpers.adoc
Documentation/gitmergeconflicts.adoc new file +339 -0
339 lines not on this page · raw message
Documentation/meson.build +1 -0
@@ -202,6 +202,7 @@ manpages = { 'gitfaq.adoc' : 7, 'gitglossary.adoc' : 7, 'gitpacking.adoc' : 7, + 'gitmergeconflicts.adoc' : 7, 'gitnamespaces.adoc' : 7, 'gitremote-helpers.adoc' : 7, 'gitrevisions.adoc' : 7,
command-list.txt +1 -0
@@ -232,6 +232,7 @@ githooks userinterfaces gitignore userinterfaces gitk mainporcelain gitmailmap userinterfaces +gitmergeconflicts guide gitmodules userinterfaces gitnamespaces guide gitprotocol-capabilities developerinterfaces
Signature · 1 line
gitgitgadget
PATCH v5 2/6 doc: git-merge: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
All of the info about merge conflicts has been moved to the new guide
--- Documentation/git-merge.adoc | 125 +---------------------------------- 1 file changed, 3 insertions(+), 122 deletions(-)
Documentation/git-merge.adoc +3 -122
@@ -49,7 +49,8 @@ a log message from the user describing the changes. Before the operation, A merge stops if there's a conflict that cannot be resolved automatically or if `--no-commit` was provided when initiating the merge. At that point you can run `git merge --abort` or `git merge ---continue`. +--continue`. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts. `git merge --abort` will abort the merge process and try to reconstruct the pre-merge state. However, if there were uncommitted changes when the
@@ -231,127 +232,6 @@ git merge v1.2.3^0 git merge --ff-only v1.2.3 ---- -HOW CONFLICTS ARE PRESENTED ---------------------------- - -During a merge, the working tree files are updated to reflect the result -of the merge. Among the changes made to the common ancestor's version, -non-overlapping ones (that is, you changed an area of the file while the -other side left that area intact, or vice versa) are incorporated in the -final result verbatim. When both sides made changes to the same area, -however, Git cannot randomly pick one side over the other, and asks you to -resolve it by leaving what both sides did to that area. - -By default, Git uses the same style as the one used by the "merge" program -from the RCS suite to present such a conflicted hunk, like this: - ------------- -Here are lines that are either unchanged from the common -ancestor, or cleanly resolved because only one side changed, -or cleanly resolved because both sides changed the same way. -<<<<<<< yours:sample.txt -Conflict resolution is hard; -let's go shopping. -======= -Git makes conflict resolution easy. ->>>>>>> theirs:sample.txt -And here is another line that is cleanly resolved or unmodified. ------------- - -The area where a pair of conflicting changes happened is marked with markers -+<<<<<<<+, `=======`, and +>>>>>>>+. The part before the `=======` -is typically your side, and the part afterwards is typically their side. - -The default format does not show what the original said in the conflicting -area. You cannot tell how many lines are deleted and replaced with -Barbie's remark on your side. The only thing you can tell is that your -side wants to say it is hard and you'd prefer to go shopping, while the -other side wants to claim it is easy. - -An alternative style can be used by setting the `merge.conflictStyle` -configuration variable to either `diff3` or `zdiff3`. In `diff3` -style, the above conflict may look like this: - ------------- -Here are lines that are either unchanged from the common -ancestor, or cleanly resolved because only one side changed, -<<<<<<< yours:sample.txt -or cleanly resolved because both sides changed the same way. -Conflict resolution is hard; -let's go shopping. -||||||| base:sample.txt -or cleanly resolved because both sides changed identically. -Conflict resolution is hard. -======= -or cleanly resolved because both sides changed the same way. -Git makes conflict resolution easy. ->>>>>>> theirs:sample.txt -And here is another line that is cleanly resolved or unmodified. ------------- - -while in `zdiff3` style, it may look like this: - ------------- -Here are lines that are either unchanged from the common -ancestor, or cleanly resolved because only one side changed, -or cleanly resolved because both sides changed the same way. -<<<<<<< yours:sample.txt -Conflict resolution is hard; -let's go shopping. -||||||| base:sample.txt -or cleanly resolved because both sides changed identically. -Conflict resolution is hard. -======= -Git makes conflict resolution easy. ->>>>>>> theirs:sample.txt -And here is another line that is cleanly resolved or unmodified. ------------- - -In addition to the +<<<<<<<+, `=======`, and +>>>>>>>+ markers, it uses -another +|||||||+ marker that is followed by the original text. You can -tell that the original just stated a fact, and your side simply gave in to -that statement and gave up, while the other side tried to have a more -positive attitude. You can sometimes come up with a better resolution by -viewing the original. - - -HOW TO RESOLVE CONFLICTS ------------------------- - -After seeing a conflict, you can do two things: - - * Decide not to merge. The only clean-ups you need are to reset - the index file to the `HEAD` commit to reverse 2. and to clean - up working tree changes made by 2. and 3.; `git merge --abort` - can be used for this. - - * Resolve the conflicts. Git will mark the conflicts in - the working tree. Edit the files into shape and - `git add` them to the index. Use `git commit` or - `git merge --continue` to seal the deal. The latter command - checks whether there is a (interrupted) merge in progress - before calling `git commit`. - -You can work through the conflict with a number of tools: - - * Use a mergetool. `git mergetool` to launch a graphical - mergetool which will work through the merge with you. - - * Look at the diffs. `git diff` will show a three-way diff, - highlighting changes from both the `HEAD` and `MERGE_HEAD` - versions. `git diff AUTO_MERGE` will show what changes you've - made so far to resolve textual conflicts. - - * Look at the diffs from each branch. `git log --merge -p <path>` - will show diffs first for the `HEAD` version and then the - `MERGE_HEAD` version. - - * Look at the originals. `git show :1:filename` shows the - common ancestor, `git show :2:filename` shows the `HEAD` - version, and `git show :3:filename` shows the `MERGE_HEAD` - version. - - EXAMPLES --------
@@ -406,6 +286,7 @@ linkgit:git-reset[1], linkgit:git-diff[1], linkgit:git-ls-files[1], linkgit:git-add[1], linkgit:git-rm[1], linkgit:git-mergetool[1] +linkgit:gitmergeconflicts[7] GIT ---
Signature · 1 line
gitgitgadget
PATCH v5 3/6 doc: git-rebase: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
Remove some of the detail about how to handle a merge conflict, since it's explained in detail in the new guide, and there probably isn't enough detail anyway.
Leave the steps since rebase is special and has a --skip option which the other commands which cause merge conflicts don't have.
--- Documentation/git-rebase.adoc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
Documentation/git-rebase.adoc +9 -4
@@ -46,10 +46,7 @@ If there is a merge conflict during this process, `git rebase` will stop at the first problematic commit and leave conflict markers. If this happens, you can do one of these things: -1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<) - and make edits to resolve the conflict. For each file you edit, you need to - tell Git that the conflict has been resolved. You can mark the conflict as - resolved with `git add <filename>`. After resolving all of the conflicts, +1. Resolve the conflict. After resolving all of the conflicts, you can continue the rebasing process with git rebase --continue
@@ -62,6 +59,9 @@ one of these things: git rebase --skip +See linkgit:gitmergeconflicts[7] (or `git help mergeconflicts`) +for a full guide to handling merge conflicts. + If you don't specify an `<upstream>` to rebase onto, the upstream configured in `branch.<name>.remote` and `branch.<name>.merge` options will be used (see linkgit:git-config[1] for details) and the `--fork-point` option is
@@ -1284,6 +1284,11 @@ include::includes/cmd-config-section-all.adoc[] include::config/rebase.adoc[] include::config/sequencer.adoc[] +SEE ALSO +-------- + +linkgit:gitmergeconflicts[7] + GIT --- Part of the linkgit:git[1] suite
Signature · 1 line
gitgitgadget
PATCH v5 4/6 doc: git-revert: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
--- Documentation/git-revert.adoc | 5 +++++ 1 file changed, 5 insertions(+)
Documentation/git-revert.adoc +5 -0
@@ -31,6 +31,10 @@ both will discard uncommitted changes in your working directory. See "Reset, restore and revert" in linkgit:git[1] for the differences between the three commands. +Reverting a commit may result in a merge conflict. +See linkgit:gitmergeconflicts[7] (or `git help mergeconflicts`) +for a guide to handling merge conflicts. + OPTIONS ------- <commit>...::
@@ -162,6 +166,7 @@ include::config/revert.adoc[] SEE ALSO -------- linkgit:git-cherry-pick[1] +linkgit:gitmergeconflicts[7] GIT ---
Signature · 1 line
gitgitgadget
PATCH v5 5/6 doc: git-cherry-pick: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
--- Documentation/git-cherry-pick.adoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
Documentation/git-cherry-pick.adoc +4 -4
@@ -19,8 +19,7 @@ Given one or more existing commits, apply the change each one introduces, recording a new commit for each. This requires your working tree to be clean (no modifications from the HEAD commit). -When it is not obvious how to apply a change, the following -happens: +When a merge conflict happens: 1. The current branch and `HEAD` pointer stay at the last commit successfully made.
@@ -36,8 +35,8 @@ happens: conflict markers `<<<<<<<` and `>>>>>>>`. 5. No other modifications are made. -See linkgit:git-merge[1] for some hints on resolving such -conflicts. +See linkgit:gitmergeconflicts[7] (or `git help mergeconflicts`) +for a guide to handling merge conflicts. OPTIONS -------
@@ -259,6 +258,7 @@ $ git cherry-pick -Xpatience topic^ <4> SEE ALSO -------- linkgit:git-revert[1] +linkgit:gitmergeconflicts[7] GIT ---
Signature · 1 line
gitgitgadget
PATCH v5 6/6 doc: git-pull: link to new merge conflicts guide
In reply to Julia Evans via GitGitGadgetFrom: Julia Evans <[email protected]>
--- Documentation/git-pull.adoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Documentation/git-pull.adoc +2 -1
@@ -38,7 +38,8 @@ or `pull.ff` with your preferred behaviour. If there's a merge conflict during the merge or rebase that you don't want to handle, you can safely abort it with `git merge --abort` or -`git rebase --abort`. +`git rebase --abort`. See linkgit:gitmergeconflicts[7] +(or `git help mergeconflicts`) for a guide to handling merge conflicts. OPTIONS -------
Signature · 1 line
gitgitgadget