All of lore.kernel.org
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: "Julia Evans via GitGitGadget" <gitgitgadget@gmail.com>
Cc: git@vger.kernel.org,  ps@pks.im,  Jeff King <peff@peff.net>,
	 "D. Ben Knoble" <ben.knoble@gmail.com>,
	 Julia Evans <julia@jvns.ca>
Subject: Re: [PATCH v3 1/6] doc: add new gitmergeconflicts man page
Date: Mon, 12 Oct 2026 11:16:53 -0700	[thread overview]
Message-ID: <xmqqwlrm7pii.fsf@gitster.g> (raw)
In-Reply-To: <7aa0ae7ec3c1d02aa1533c27fa40f4815c03ba6e.1791816795.git.gitgitgadget@gmail.com> (Julia Evans via GitGitGadget's message of "Mon, 12 Oct 2026 14:53:10 +0000")

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


  reply	other threads:[~2026-10-12 18:16 UTC|newest]

Thread overview: 83+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-24 14:44 [PATCH 0/7] [doc] Add new page on merge conflicts Julia Evans via GitGitGadget
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
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
2026-09-24 14:44 ` [PATCH 2/7] [doc] git-merge: link to new merge conflicts guide Julia Evans via GitGitGadget
2026-09-25 16:36   ` D. Ben Knoble
2026-09-25 16:59     ` Julia Evans
2026-09-25 18:19       ` Junio C Hamano
2026-09-25 19:32         ` Ben Knoble
2026-09-25 21:49           ` Junio C Hamano
2026-09-25 19:34       ` Ben Knoble
2026-10-02 17:01       ` Julia Evans
2026-10-02 17:50         ` Junio C Hamano
2026-10-02 18:53           ` Julia Evans
2026-10-02 21:38             ` Junio C Hamano
2026-10-03  2:25         ` D. Ben Knoble
2026-10-03  4:12           ` Junio C Hamano
2026-09-30 13:19   ` Patrick Steinhardt
2026-09-24 14:44 ` [PATCH 3/7] [doc] git-rebase: " Julia Evans via GitGitGadget
2026-09-24 14:44 ` [PATCH 4/7] [doc] git-revert: " Julia Evans via GitGitGadget
2026-09-24 14:44 ` [PATCH 5/7] [doc] git-cherry-pick: " Julia Evans via GitGitGadget
2026-09-25 17:17   ` Junio C Hamano
2026-09-28 20:58     ` Julia Evans
2026-09-28 21:25       ` Junio C Hamano
2026-09-24 14:44 ` [PATCH 6/7] [doc] git-pull: " Julia Evans via GitGitGadget
2026-09-24 14:44 ` [PATCH 7/7] [doc] ignore conflict markers in gitmergeconflicts.adoc Julia Evans via GitGitGadget
2026-10-07 21:21   ` Junio C Hamano
2026-10-09 12:06     ` Julia Evans
2026-09-24 22:20 ` [PATCH 0/7] [doc] Add new page on merge conflicts Junio C Hamano
2026-09-24 23:37   ` Jeff King
2026-09-28 20:41     ` Julia Evans
2026-09-29  1:32       ` Jeff King
2026-09-29  1:56         ` Junio C Hamano
2026-09-25 16:25 ` D. Ben Knoble
2026-10-02 17:39   ` Julia Evans
2026-10-03  2:29     ` D. Ben Knoble
2026-10-05 18:49       ` Julia Evans
2026-10-06 16:53         ` D. Ben Knoble
2026-10-06 17:09           ` D. Ben Knoble
2026-10-09 12:00 ` [PATCH v2 0/6] " Julia Evans via GitGitGadget
2026-10-09 12:00   ` [PATCH v2 1/6] doc: add new gitmergeconflicts man page Julia Evans via GitGitGadget
2026-10-09 17:58     ` Junio C Hamano
2026-10-09 18:53       ` Julia Evans
2026-10-09 21:54         ` Junio C Hamano
2026-10-10  1:45         ` Junio C Hamano
2026-10-09 12:00   ` [PATCH v2 2/6] doc: git-merge: link to new merge conflicts guide Julia Evans via GitGitGadget
2026-10-09 18:20     ` Junio C Hamano
2026-10-09 12:00   ` [PATCH v2 3/6] doc: git-rebase: " Julia Evans via GitGitGadget
2026-10-09 18:22     ` Junio C Hamano
2026-10-09 12:00   ` [PATCH v2 4/6] doc: git-revert: " Julia Evans via GitGitGadget
2026-10-09 18:24     ` Junio C Hamano
2026-10-09 12:00   ` [PATCH v2 5/6] doc: git-cherry-pick: " Julia Evans via GitGitGadget
2026-10-09 18:26     ` Junio C Hamano
2026-10-09 20:12       ` Julia Evans
2026-10-09 12:00   ` [PATCH v2 6/6] doc: git-pull: " Julia Evans via GitGitGadget
2026-10-09 18:27     ` Junio C Hamano
2026-10-09 15:41   ` [PATCH v2 0/6] [doc] Add new page on merge conflicts Junio C Hamano
2026-10-09 15:53     ` Julia Evans
2026-10-09 22:10     ` Ben Knoble
2026-10-09 18:36   ` Junio C Hamano
2026-10-12 14:53 ` [PATCH v3 " Julia Evans via GitGitGadget
2026-10-12 14:53   ` [PATCH v3 1/6] doc: add new gitmergeconflicts man page Julia Evans via GitGitGadget
2026-10-12 18:16     ` Junio C Hamano [this message]
2026-10-13 11:07     ` Patrick Steinhardt
2026-10-12 14:53   ` [PATCH v3 2/6] doc: git-merge: link to new merge conflicts guide Julia Evans via GitGitGadget
2026-10-12 14:53   ` [PATCH v3 3/6] doc: git-rebase: " Julia Evans via GitGitGadget
2026-10-12 14:53   ` [PATCH v3 4/6] doc: git-revert: " Julia Evans via GitGitGadget
2026-10-12 14:53   ` [PATCH v3 5/6] doc: git-cherry-pick: " Julia Evans via GitGitGadget
2026-10-13 11:07     ` Patrick Steinhardt
2026-10-12 14:53   ` [PATCH v3 6/6] doc: git-pull: " Julia Evans via GitGitGadget
2026-10-12 15:53   ` [PATCH v3 0/6] [doc] Add new page on merge conflicts D. Ben Knoble
2026-10-12 20:44     ` Julia Evans
2026-10-12 18:17   ` Junio C Hamano
2026-10-12 18:37     ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xmqqwlrm7pii.fsf@gitster.g \
    --to=gitster@pobox.com \
    --cc=ben.knoble@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitgitgadget@gmail.com \
    --cc=julia@jvns.ca \
    --cc=peff@peff.net \
    --cc=ps@pks.im \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.