Skip to content

[doc] Add new page on merge conflicts - #2237

Open
jvns wants to merge 6 commits into
gitgitgadget:masterfrom
jvns:merge-conflicts
Open

jvns wants to merge 6 commits into
gitgitgadget:masterfrom
jvns:merge-conflicts

Conversation

@jvns

@jvns jvns commented Sep 23, 2026 •

Copy link
Copy Markdown

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-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
  • Don't mention zdiff3 anymore (in an attempt to deal with Patrick's comments)
  • clarify 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)

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.

CC: ps@pks.im
cc: Jeff King peff@peff.net
cc: "D. Ben Knoble" ben.knoble@gmail.com

@gitgitgadget

gitgitgadget Bot commented Sep 23, 2026

Copy link
Copy Markdown

There is an issue in commit 7dee697:
[doc] Add new gitmergeconflicts man page

  • Commit not signed off

@gitgitgadget

gitgitgadget Bot commented Sep 23, 2026

Copy link
Copy Markdown

There is an issue in commit 3a9e01d:
[doc] git-merge: link to new merge conflicts guide

  • Commit not signed off

@gitgitgadget

gitgitgadget Bot commented Sep 23, 2026

Copy link
Copy Markdown

There is an issue in commit c96ce90:
[doc] git-rebase: link to new merge conflicts guide

  • Commit not signed off

@gitgitgadget

gitgitgadget Bot commented Sep 23, 2026

Copy link
Copy Markdown

There are issues in commit a340474:
[doc] git-revert: link to new merge conflicts guide

  • Commit checks stopped - the message is too short
  • Commit not signed off

@gitgitgadget

gitgitgadget Bot commented Sep 23, 2026

Copy link
Copy Markdown

There is an issue in commit 67302e7:
[doc] git-cherry-pick: link to new merge conflicts guide

  • Commit not signed off

@gitgitgadget

gitgitgadget Bot commented Sep 23, 2026

Copy link
Copy Markdown

There are issues in commit 241bf3e:
[doc] git-pull: link to new merge conflicts guide

  • Commit checks stopped - the message is too short
  • Commit not signed off

@jvns jvns changed the title Merge conflicts [doc] Add new page on merge conflicts Sep 23, 2026
@jvns
jvns force-pushed the merge-conflicts branch 3 times, most recently from 9058e0a to 420858b Compare September 23, 2026 15:44
@jvns

jvns commented Sep 23, 2026 •

Copy link
Copy Markdown
Author

The check_whitespace job is failing because of merge conflict markers, but the reason there are merge conflict markers is that we're documenting how to handle merge conflicts. Not sure what to do about that.

(edit: I think it's in .gitattributes)

@dscho

dscho commented Sep 23, 2026

Copy link
Copy Markdown
Member

The check_whitespace job is failing because of merge conflict markers, but the reason there are merge conflict markers is that we're documenting how to handle merge conflicts.

Yep: see e.g. https://github.com/git/git/blob/v2.55.0/.gitattributes#L16

@jvns

jvns commented Sep 23, 2026

Copy link
Copy Markdown
Author

Not sure what's going on with the debian-12 test failure but I'm planning to ignore it for now.

@dscho

dscho commented Sep 23, 2026

Copy link
Copy Markdown
Member

Not sure what's going on with the debian-12 test failure but I'm planning to ignore it for now.

@jvns see here: #2236. You can safely ignore it.

@jvns

jvns commented Sep 23, 2026

Copy link
Copy Markdown
Author

thanks, appreciate your work on testing!

@jvns

jvns commented Sep 23, 2026

Copy link
Copy Markdown
Author

/preview

@gitgitgadget

gitgitgadget Bot commented Sep 23, 2026

Copy link
Copy Markdown

Preview email sent as pull.2237.git.1790185498.gitgitgadget@gmail.com

@jvns

jvns commented Sep 24, 2026

Copy link
Copy Markdown
Author

/submit

@gitgitgadget

gitgitgadget Bot commented Sep 24, 2026

Copy link
Copy Markdown

Submitted as pull.2237.git.1790261062.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-2237/jvns/merge-conflicts-v1

To fetch this version to local tag pr-2237/jvns/merge-conflicts-v1:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-2237/jvns/merge-conflicts-v1

@gitgitgadget

gitgitgadget Bot commented Sep 24, 2026

Copy link
Copy Markdown

This patch series was integrated into seen via git@a459886.

@gitgitgadget gitgitgadget Bot added the seen label Sep 24, 2026
Comment thread Documentation/Makefile
@@ -58,6 +58,7 @@ MAN7_TXT += gitdiffcore.adoc
MAN7_TXT += giteveryday.adoc

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

"Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:

>  Documentation/Makefile               |   1 +
>  Documentation/gitmergeconflicts.adoc | 294 +++++++++++++++++++++++++++
>  Documentation/meson.build            |   1 +
>  3 files changed, 296 insertions(+)
>  create mode 100644 Documentation/gitmergeconflicts.adoc
>
> diff --git a/Documentation/Makefile b/Documentation/Makefile
> index f8dea4b395..bc49641dda 100644
> --- a/Documentation/Makefile
> +++ b/Documentation/Makefile
> @@ -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(+)

diff --git c/Documentation/meson.build w/Documentation/meson.build
index 51647957e0..10b0637991 100644
--- c/Documentation/meson.build
+++ w/Documentation/meson.build
@@ -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,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

Junio C Hamano <gitster@pobox.com> writes:

> 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.

> 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.

>
>
>  Documentation/meson.build | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git c/Documentation/meson.build w/Documentation/meson.build
> index 51647957e0..10b0637991 100644
> --- c/Documentation/meson.build
> +++ w/Documentation/meson.build
> @@ -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,

@gitgitgadget

gitgitgadget Bot commented Sep 25, 2026

Copy link
Copy Markdown

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

"Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:

> 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.

@gitgitgadget

gitgitgadget Bot commented Sep 25, 2026

Copy link
Copy Markdown

Jeff King wrote on the Git mailing list (how to reply to this email):

On Thu, Sep 24, 2026 at 03:20:30PM -0700, Junio C Hamano wrote:

> "Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
> 
> > 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

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

@gitgitgadget

gitgitgadget Bot commented Sep 25, 2026

Copy link
Copy Markdown

User Jeff King <peff@peff.net> has been added to the cc: list.

@gitgitgadget

gitgitgadget Bot commented Sep 25, 2026

Copy link
Copy Markdown

"D. Ben Knoble" wrote on the Git mailing list (how to reply to this email):

A big thank you for working on this.

On Thu, Sep 24, 2026 at 10:46 AM Julia Evans via GitGitGadget
<gitgitgadget@gmail.com> wrote:
>
> 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.

See also discussion in
https://lore.kernel.org/git/CABPp-BEQSx4m3BcT28CpVGCtsH75+x3gmv4OJz_ecLVLx+kBWg@mail.gmail.com/T/#t

>  * 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!

> 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.

>  * 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.

>  * 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!

>  * 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.

My most frequently use is "git show REBASE_HEAD" (which is what "git
rebase --show-current-patch" does, albeit with more typing). :shrug:

-- 
D. Ben Knoble

@gitgitgadget

gitgitgadget Bot commented Sep 25, 2026

Copy link
Copy Markdown

User "D. Ben Knoble" <ben.knoble@gmail.com> has been added to the cc: list.

@@ -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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"D. Ben Knoble" wrote on the Git mailing list (how to reply to this email):

Hi Julia,

On Thu, Sep 24, 2026 at 10:46 AM Julia Evans via GitGitGadget
<gitgitgadget@gmail.com> wrote:
>
> From: Julia Evans <julia@jvns.ca>
>
> All of the info about merge conflicts has been moved to the new guide

> 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.

> - * 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.

-- 
D. Ben Knoble

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Julia Evans" wrote on the Git mailing list (how to reply to this email):

On Fri, Sep 25, 2026, at 12:36 PM, D. Ben Knoble wrote:
> Hi Julia,
>
> On Thu, Sep 24, 2026 at 10:46 AM Julia Evans via GitGitGadget
> <gitgitgadget@gmail.com> wrote:
>>
>> From: Julia Evans <julia@jvns.ca>
>>
>> All of the info about merge conflicts has been moved to the new guide
>
>> 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.
>
>> - * 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.

Will think about this!

> 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:

> `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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

"Julia Evans" <julia@jvns.ca> writes:

> 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.

>> `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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ben Knoble wrote on the Git mailing list (how to reply to this email):

> Le 25 sept. 2026 à 14:19, Junio C Hamano <gitster@pobox.com> a écrit :
> 
> "Julia Evans" <julia@jvns.ca> writes:
> 
>> 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 ;)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ben Knoble wrote on the Git mailing list (how to reply to this email):

> Le 25 sept. 2026 à 12:59, Julia Evans <julia@jvns.ca> a écrit :
> 
> 
> 
>> On Fri, Sep 25, 2026, at 12:36 PM, D. Ben Knoble wrote:
>> Hi Julia,

[snip]

>> 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:
> 
>> `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.

That reads well enough for me! Thanks. 

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

"Julia Evans" <julia@jvns.ca> writes:

> 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.

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.

>     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".

>     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".

>     * 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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Julia Evans" wrote on the Git mailing list (how to reply to this email):

>>     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.
>
> Some immediate reactions.

Thanks, incorporated a few of these ("it marks them as conflicted",
"since there's no overlap", "the same file")

>>     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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

"Julia Evans" <julia@jvns.ca> writes:

>>  - "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.

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.

;-).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"D. Ben Knoble" wrote on the Git mailing list (how to reply to this email):

On Fri, Oct 2, 2026 at 1:01 PM Julia Evans <julia@jvns.ca> wrote:
>
>
>
> On Fri, Sep 25, 2026, at 12:59 PM, Julia Evans wrote:
> > On Fri, Sep 25, 2026, at 12:36 PM, D. Ben Knoble wrote:
> >> Hi Julia,
> >>
> >> On Thu, Sep 24, 2026 at 10:46 AM Julia Evans via GitGitGadget
> >> <gitgitgadget@gmail.com> wrote:
> >>>
> >>> From: Julia Evans <julia@jvns.ca>
> >>>
> >>> All of the info about merge conflicts has been moved to the new guide
> >>
> >>> 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.
>
> >> 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!
>
> 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.
>

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).

-- 
D. Ben Knoble

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

"D. Ben Knoble" <ben.knoble@gmail.com> writes:

> 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.

@gitgitgadget

gitgitgadget Bot commented Oct 9, 2026

Copy link
Copy Markdown

Ben Knoble wrote on the Git mailing list (how to reply to this email):

> Le 9 oct. 2026 à 11:41, Junio C Hamano <gitster@pobox.com> a écrit :
> 
> > "Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
> 
> For example, you added Ben and Patrick to the trailer of patch #1.
> 
>> Range-diff vs v1:
>> 
>> 1:  ad4853dc36 ! 1:  ab0344f947 [doc] Add new gitmergeconflicts man page
>>     @@ Metadata
>>      Author: Julia Evans <julia@jvns.ca>
>> 
>>       ## Commit message ##
>>     -    [doc] Add new gitmergeconflicts man page
>>     +    doc: add new gitmergeconflicts man page
>> ...
>>          Co-Authored-By: Marie Claire LeBlanc Flanagan <hello@marieflanagan.com>
>>     +    Reviewed-by: D. Ben Knoble <ben.knoble+github@gmail.com>
>>     +    Reviewed-by: Patrick Steinhardt <ps@pks.im>
>>          Signed-off-by: Julia Evans <julia@jvns.ca>

PS I think I just use my non-suffixed email on this project; 
see our .mailmap :)

@gitgitgadget

gitgitgadget Bot commented Oct 10, 2026

Copy link
Copy Markdown

There was a status update in the "Cooking" section about the branch je/doc-merge-conflicts on the Git mailing list:

A new user manual page on how to resolve merge conflicts has been
introduced, and other commands that could encounter conflicts have
been updated to link to it.

Expecting a reroll.
cf. <xmqqse2evq2k.fsf@gitster.g>
cf. <2a721921-2865-4cc4-8cd2-01eae74f27a5@app.fastmail.com>
source: <pull.2237.v2.git.1791547213.gitgitgadget@gmail.com>

@gitgitgadget

gitgitgadget Bot commented Oct 10, 2026

Copy link
Copy Markdown

This patch series was integrated into seen via git@5101b07.

@gitgitgadget gitgitgadget Bot added the seen label Oct 10, 2026
@jvns

jvns commented Oct 12, 2026

Copy link
Copy Markdown
Author

/submit

@gitgitgadget

gitgitgadget Bot commented Oct 12, 2026

Copy link
Copy Markdown

Submitted as pull.2237.v3.git.1791816795.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-2237/jvns/merge-conflicts-v3

To fetch this version to local tag pr-2237/jvns/merge-conflicts-v3:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-2237/jvns/merge-conflicts-v3

@gitgitgadget

gitgitgadget Bot commented Oct 12, 2026

Copy link
Copy Markdown

"D. Ben Knoble" wrote on the Git mailing list (how to reply to this email):

On Mon, Oct 12, 2026 at 10:53 AM Julia Evans via GitGitGadget
<gitgitgadget@gmail.com> wrote:
>
> 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`.
>      +
>           Co-Authored-By: Marie Claire LeBlanc Flanagan <hello@marieflanagan.com>
>      -    Reviewed-by: D. Ben Knoble <ben.knoble+github@gmail.com>
>      -    Reviewed-by: Patrick Steinhardt <ps@pks.im>
>      +    Helped-by: D. Ben Knoble <ben.knoble+github@gmail.com>

Maybe this got lost in the shuffle, but I do prefer to use
<ben.knoble@gmail.com> for Git these days, thanks!

>      +    Helped-by: Patrick Steinhardt <ps@pks.im>
>      +    Signed-off-by: Julia Evans <julia@jvns.ca>
>      +    Signed-off-by: Marie Claire LeBlanc Flanagan <hello@marieflanagan.com>
>           Signed-off-by: Julia Evans <julia@jvns.ca>

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

-- 
D. Ben Knoble

@gitgitgadget

gitgitgadget Bot commented Oct 12, 2026

Copy link
Copy Markdown

This patch series is no longer integrated into seen.

@gitgitgadget gitgitgadget Bot removed the seen label Oct 12, 2026
Comment thread .gitattributes
@@ -14,6 +14,7 @@ CODE_OF_CONDUCT.md -whitespace
/t/oid-info/* text eol=lf

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

"Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:

> From: Julia Evans <julia@jvns.ca>
>
> 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
> ...
> - 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.

> 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`.

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.

> diff --git a/Documentation/gitmergeconflicts.adoc b/Documentation/gitmergeconflicts.adoc
> ...
> +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.

> +[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".
> +================================

OK.

> +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.

> +----
> +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:
> +
> +----
> +FRUITS = [
> +    "apple",
> +    "banana",
> +    "cherry",
> +    "mango",
> +    "orange",
> +]
> +----

So, this is one possible resolution.  We cannot tell if it is the
correct one.

> +[[tools]]
> +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.

> +[[diff3]]
> +DIFF3
> +-----
> +
> +By default, Git doesn't include the original code when formatting
> +a merge conflict. To include the original code, you can set the
> +configuration option `merge.conflictstyle` to `diff3`.
> +This extra context can make it much easier to understand what's
> +happening in a merge conflict.
> +
> +Here's an example of what a merge conflict would look like when using
> +`diff3`. There's an extra section (between `|||||||` and `=======`)
> +with the original code.
> +
> +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",
> +    "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 ...

> +[NOTE]
> +================================
> +`zdiff3` is an alternative to `diff3` that 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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Julia Evans" wrote on the Git mailing list (how to reply to this email):

On Mon, Oct 12, 2026, at 2:16 PM, Junio C Hamano wrote:
> "Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:
>
>> From: Julia Evans <julia@jvns.ca>
>>
>> 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
>> ...
>> - 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.

>> 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`.
>
> 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.

> 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.
>
>> diff --git a/Documentation/gitmergeconflicts.adoc b/Documentation/gitmergeconflicts.adoc
>> ...
>> +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.

Done.

>> +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".

>> +[[diff3]]
>> +DIFF3
>> +-----
>> +
>> +By default, Git doesn't include the original code when formatting
>> +a merge conflict. To include the original code, you can set the
>> +configuration option `merge.conflictstyle` to `diff3`.
>> +This extra context can make it much easier to understand what's
>> +happening in a merge conflict.
>> +
>> +Here's an example of what a merge conflict would look like when using
>> +`diff3`. There's an extra section (between `|||||||` and `=======`)
>> +with the original code.
>> +
>> +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",
>> +    "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.

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.

> 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 ...
>
>> +[NOTE]
>> +================================
>> +`zdiff3` is an alternative to `diff3` that 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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

"Julia Evans" <julia@jvns.ca> writes:

>> 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.

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.

>> 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.

@gitgitgadget

gitgitgadget Bot commented Oct 12, 2026

Copy link
Copy Markdown

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

"Julia Evans via GitGitGadget" <gitgitgadget@gmail.com> writes:

> 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.

@gitgitgadget

gitgitgadget Bot commented Oct 12, 2026

Copy link
Copy Markdown

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

Junio C Hamano <gitster@pobox.com> writes:

> 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(-)

diff --git c/Documentation/gitmergeconflicts.adoc w/Documentation/gitmergeconflicts.adoc
index 3c6eaaddf8..eeeeac85c0 100644
--- c/Documentation/gitmergeconflicts.adoc
+++ w/Documentation/gitmergeconflicts.adoc
@@ -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

@gitgitgadget

gitgitgadget Bot commented Oct 12, 2026

Copy link
Copy Markdown

"Julia Evans" wrote on the Git mailing list (how to reply to this email):

On Mon, Oct 12, 2026, at 11:53 AM, D. Ben Knoble wrote:
> On Mon, Oct 12, 2026 at 10:53 AM Julia Evans via GitGitGadget
> <gitgitgadget@gmail.com> wrote:
>>
>> 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`.
>>      +
>>           Co-Authored-By: Marie Claire LeBlanc Flanagan <hello@marieflanagan.com>
>>      -    Reviewed-by: D. Ben Knoble <ben.knoble+github@gmail.com>
>>      -    Reviewed-by: Patrick Steinhardt <ps@pks.im>
>>      +    Helped-by: D. Ben Knoble <ben.knoble+github@gmail.com>
>
> Maybe this got lost in the shuffle, but I do prefer to use
> <ben.knoble@gmail.com> for Git these days, thanks!

Oops, I meant to fix that, thanks for pointing it out!

>>      +    Helped-by: Patrick Steinhardt <ps@pks.im>
>>      +    Signed-off-by: Julia Evans <julia@jvns.ca>
>>      +    Signed-off-by: Marie Claire LeBlanc Flanagan <hello@marieflanagan.com>
>>           Signed-off-by: Julia Evans <julia@jvns.ca>
>
> 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 :)

Comment thread .gitattributes
@@ -14,6 +14,7 @@ CODE_OF_CONDUCT.md -whitespace
/t/oid-info/* text eol=lf

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Patrick Steinhardt wrote on the Git mailing list (how to reply to this email):

On Mon, Oct 12, 2026 at 02:53:10PM +0000, Julia Evans via GitGitGadget wrote:
> diff --git a/Documentation/gitmergeconflicts.adoc b/Documentation/gitmergeconflicts.adoc
> new file mode 100644
> index 0000000000..3c6eaaddf8
> --- /dev/null
> +++ b/Documentation/gitmergeconflicts.adoc
> @@ -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
> +  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.

> +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.

Same nit here.

> +[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.".

> +[[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.

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.

> +[[tools]]
> +TOOLS FOR HANDLING MERGE CONFLICTS
> +----------------------------------
> +
> +Here are some ways to get extra context while handling a merge conflict:
> +
> +* There are many graphical "merge tools" for Git, which will normally
> +  show you the different versions of the code side by side.
> +  If you have a mergetool configured, `git mergetool` will launch it.
> +  See also `merge.tool` in linkgit:git-config[1] for a list of
> +  the mergetools Git supports.
> +
> +* You can set the configuration variable `merge.conflictstyle=diff3`.
> +  See <<diff3,DIFF3>> below for more.
> +
> +* `git log --merge -p <filename>`  will list all commits which

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.

> +[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"?

> +[[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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Julia Evans" wrote on the Git mailing list (how to reply to this email):

On Tue, Oct 13, 2026, at 7:07 AM, Patrick Steinhardt wrote:
> On Mon, Oct 12, 2026 at 02:53:10PM +0000, Julia Evans via GitGitGadget wrote:
>> diff --git a/Documentation/gitmergeconflicts.adoc b/Documentation/gitmergeconflicts.adoc
>> new file mode 100644
>> index 0000000000..3c6eaaddf8
>> --- /dev/null
>> +++ b/Documentation/gitmergeconflicts.adoc
>> @@ -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
>> +  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.

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.

>> +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.
>
> Same nit here.

>> +[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.

>> +[[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.
>
> 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.
>
>> +[[tools]]
>> +TOOLS FOR HANDLING MERGE CONFLICTS
>> +----------------------------------
>> +
>> +Here are some ways to get extra context while handling a merge conflict:
>> +
>> +* There are many graphical "merge tools" for Git, which will normally
>> +  show you the different versions of the code side by side.
>> +  If you have a mergetool configured, `git mergetool` will launch it.
>> +  See also `merge.tool` in linkgit:git-config[1] for a list of
>> +  the mergetools Git supports.
>> +
>> +* You can set the configuration variable `merge.conflictstyle=diff3`.
>> +  See <<diff3,DIFF3>> below for more.
>> +
>> +* `git log --merge -p <filename>`  will list all commits which
>
> 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.

Good idea, will do.

>> +[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.

>> +[[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.

Interesting, I didn't know it could be something other than a commit.

>
> Other than this handful of nits I'm happy with this version, thanks!
>
> Patrick

thanks for the review!

@@ -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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Patrick Steinhardt wrote on the Git mailing list (how to reply to this email):

On Mon, Oct 12, 2026 at 02:53:14PM +0000, Julia Evans via GitGitGadget wrote:
> From: Julia Evans <julia@jvns.ca>
> 
> 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

@gitgitgadget

gitgitgadget Bot commented Oct 13, 2026

Copy link
Copy Markdown

This patch series was integrated into seen via git@f7df9cd.

@gitgitgadget gitgitgadget Bot added the seen label Oct 13, 2026
@gitgitgadget

gitgitgadget Bot commented Oct 14, 2026

Copy link
Copy Markdown

There was a status update in the "Cooking" section about the branch je/doc-merge-conflicts on the Git mailing list:

A new user manual page on how to resolve merge conflicts has been
introduced, and other commands that could encounter conflicts have
been updated to link to it.

Waiting for response.
cf. <xmqqwlrm7pii.fsf@gitster.g>
cf. <as4RC-g606poy2WB@pks.im>
source: <pull.2237.v3.git.1791816795.gitgitgadget@gmail.com>

@jvns
jvns force-pushed the merge-conflicts branch 2 times, most recently from 1e1c6ef to c3b635a Compare October 14, 2026 19:58
@gitgitgadget

gitgitgadget Bot commented Oct 14, 2026

Copy link
Copy Markdown

There are issues in commit 757ff66:
fixup! doc: add new gitmergeconflicts man page

  • Commit checks stopped - the message is too short
  • Rebase needed to squash commit
  • Commit not signed off

@gitgitgadget

gitgitgadget Bot commented Oct 14, 2026

Copy link
Copy Markdown

There are issues in commit 538910f:
fixup! doc: add new gitmergeconflicts man page

  • Commit checks stopped - the message is too short
  • Rebase needed to squash commit
  • Commit not signed off

jvns and others added 6 commits October 14, 2026 16:22
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.

Co-Authored-By: Marie Claire LeBlanc Flanagan <hello@marieflanagan.com>
Helped-by: D. Ben Knoble <ben.knoble@gmail.com>
Helped-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Marie Claire LeBlanc Flanagan <hello@marieflanagan.com>
Signed-off-by: Julia Evans <julia@jvns.ca>
All of the info about merge conflicts has been moved to the new guide

Signed-off-by: Julia Evans <julia@jvns.ca>
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.

Signed-off-by: Julia Evans <julia@jvns.ca>
Signed-off-by: Julia Evans <julia@jvns.ca>
Signed-off-by: Julia Evans <julia@jvns.ca>
Signed-off-by: Julia Evans <julia@jvns.ca>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants