All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Julia Evans via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: ps@pks.im, Jeff King <peff@peff.net>,
	"D. Ben Knoble" <ben.knoble@gmail.com>,
	Julia Evans <julia@jvns.ca>
Subject: [PATCH v3 0/6] [doc] Add new page on merge conflicts
Date: Mon, 12 Oct 2026 14:53:09 +0000	[thread overview]
Message-ID: <pull.2237.v3.git.1791816795.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2237.git.1790261062.gitgitgadget@gmail.com>

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

some non-changes in v3:

 * didn't add any extra Reviewed-by
 * "return your branch to its original state": left the same because during
   a multistep cherry-pick the branch does need to be returned to its
   original state
 * leave the explanation of AUTO_MERGE the same since Marie says it's more
   clear this way
 * leave contractions alone for now
 * don't say semantic merge applies to all merges since I think that will be
   clear to readers
 * the wording of "When Git merges two commits together" is a bit weird but
   we don't have a better idea right now
 * don't explain --left-right. Can be very easily added in the future if we
   think it's important.

Thanks to Lobo, Adam Svahn, Louis Vanier, David Turner, Ben Zanin, Salih,
and about 12 others who gave feedback on both the original git merge man
page, as well as the proposed improvements.

Julia Evans (6):
  doc: add new gitmergeconflicts man page
  doc: git-merge: link to new merge conflicts guide
  doc: git-rebase: link to new merge conflicts guide
  doc: git-revert: link to new merge conflicts guide
  doc: git-cherry-pick: link to new merge conflicts guide
  doc: git-pull: link to new merge conflicts guide

 .gitattributes                       |   1 +
 Documentation/Makefile               |   1 +
 Documentation/git-cherry-pick.adoc   |   8 +-
 Documentation/git-merge.adoc         | 125 +---------
 Documentation/git-pull.adoc          |   3 +-
 Documentation/git-rebase.adoc        |  13 +-
 Documentation/git-revert.adoc        |   5 +
 Documentation/gitmergeconflicts.adoc | 330 +++++++++++++++++++++++++++
 Documentation/meson.build            |   1 +
 command-list.txt                     |   1 +
 10 files changed, 357 insertions(+), 131 deletions(-)
 create mode 100644 Documentation/gitmergeconflicts.adoc


base-commit: 3bc0341126508f78f5869cbfc0005e987efdf0c7
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2237%2Fjvns%2Fmerge-conflicts-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2237/jvns/merge-conflicts-v3
Pull-Request: https://github.com/gitgitgadget/git/pull/2237

Range-diff vs v2:

 1:  ab0344f947 ! 1:  7aa0ae7ec3 doc: add new gitmergeconflicts man page
     @@ Commit message
          place, since it's a really nice example of a place Git has a consistent
          interface between similar commands.
      
     +    Only discuss merge, rebase, cherry-pick, and revert for now even though
     +    there are other ways that merge conflicts can happen because it's
     +    awkward to talk about `am`, `apply`, and `checkout -m`.
     +
          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>
     +    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>
      
       ## .gitattributes ##
     @@ Documentation/gitmergeconflicts.adoc (new)
      +-----------
      +
      +Merge conflicts can happen during a `git merge`, `git rebase`, `git
     -+cherry-pick`, `git pull`, or `git revert`. All of those commands use
     -+the same merge algorithm, and the process for resolving a merge conflict
     -+is always very similar.
     ++cherry-pick`, `git pull`, `git revert`, or any other command that does
     ++a merge. All of those commands use the same merge algorithm, and the
     ++process for resolving a merge conflict is always very similar.
      +
     -+The most common ways to handle a merge conflict are:
     ++There are 3 ways to handle a merge conflict:
      +
      +* Resolve the conflict. (see <<resolve,HOW TO RESOLVE A MERGE CONFLICT>>
      +  below for details)
     -+* Or stop the operation and return your branch to its original state
     ++* Stop the operation and return your branch to its original state
      +  with the appropriate `--abort` command, for example `git merge --abort`
      +  or `git rebase --abort`. See <<git_status,EXAMPLE: GIT STATUS OUTPUT>> below
      +  for how to find the command to run.
     ++* Or (if you're in a multi-step rebase or cherry-pick) skip the problematic
     ++  commit with the appropriate `--skip` command
      +
      +WHAT IS A MERGE CONFLICT?
      +-------------------------
     @@ Documentation/gitmergeconflicts.adoc (new)
      +  sides' edits in the file, and leaves <<markers, merge conflict markers>>
      +  that you need to resolve.
      +
     ++[NOTE]
     ++================================
     ++Even if Git successfully merges both sides with no conflicts, it's
     ++possible to end up with code that doesn't work. For example, this can
     ++happen if one side renames a function, and the other side adds a call to
     ++the old function. This is called a "semantic merge conflict".
     ++================================
     ++
      +[[markers]]
      +MERGE CONFLICT MARKERS
      +----------------------
     @@ Documentation/gitmergeconflicts.adoc (new)
      +When there's a merge conflict, Git will update the conflicted file
      +to include merge conflict markers `<<<<<<<`, `=======`, and `>>>>>>>`.
      +For example, here's a merge conflict where both sides edited a list of
     -+fruits in different ways:
     ++fruits in different ways -- one side added "cherry" and the other side
     ++added "banana":
      +
      +----
      +FRUITS = [
     @@ Documentation/gitmergeconflicts.adoc (new)
      +    "apple",
      +<<<<<<< HEAD
      +    "cherry",
     -+    "mango",
      +=======
      +    "banana",
     -+    "mango",
      +>>>>>>> add-fruit
     ++    "mango",
      +    "orange",
      +]
      +----
     @@ Documentation/gitmergeconflicts.adoc (new)
      +  See also `merge.tool` in linkgit:git-config[1] for a list of
      +  the mergetools Git supports.
      +
     -+* You can set the configuration option `merge.conflictstyle=diff3`.
     -+  See <<diff3,DIFF3 AND ZDIFF3>> below for more.
     ++* You can set the configuration variable `merge.conflictstyle=diff3`.
     ++  See <<diff3,DIFF3>> below for more.
      +
      +* `git log --merge -p <filename>`  will list all commits which
      +  caused the merge conflict for `<filename>`, and the diff
     @@ Documentation/gitmergeconflicts.adoc (new)
      +* Look at the original files.  `git show :1:filename` shows the
      +  common ancestor, `git show :2:filename` shows the "ours"
      +  version, and `git show :3:filename` shows the "theirs"
     -+  version.
     ++  version. See <<ours,"OURS" AND "THEIRS">> below for more on
     ++  "ours" and "theirs".
      +
      +Here are some ways to track your progress while handling a conflict:
      +
     @@ Documentation/gitmergeconflicts.adoc (new)
      +
      +* Use `git diff AUTO_MERGE` to show what changes you've made so far to
      +  resolve the conflicts.
     ++  See <<automerge,EXAMPLE OF USING `AUTO_MERGE`>> below for more.
      +
      +[[git_status]]
      +EXAMPLE: GIT STATUS OUTPUT
     @@ Documentation/gitmergeconflicts.adoc (new)
      +  original state
      +* you should run `git rebase --continue` when you're done resolving all
      +  the conflicts
     -+* there's one file left with conflicts in it: `fruits.py`
     ++* the conflicts in `fruits.py` haven't been marked as resolved
      +
      +----
      +$ git status
     @@ Documentation/gitmergeconflicts.adoc (new)
      +
      +
      +[[diff3]]
     -+DIFF3 AND ZDIFF3
     -+----------------
     ++DIFF3
     ++-----
      +
      +By default, Git doesn't include the original code when formatting
      +a merge conflict. To include the original code, you can set the
     -+configuration option `merge.conflictstyle` to `diff3` or `zdiff3`.
     ++configuration option `merge.conflictstyle` to `diff3`.
      +This extra context can make it much easier to understand what's
      +happening in a merge conflict.
      +
      +Here's an example of what a merge conflict would look like when using
     -+`diff3`. It shows, in order, the "ours" side of the conflict, the
     -+original code (`"mangoooo"`), and the "theirs" side of the
     -+conflict. With this view, you can see that both sides fixed the spelling
     ++`diff3`. There's an extra section (between `|||||||` and `=======`)
     ++with the original code.
     ++
     ++With this view, you can see that both sides fixed a spelling
      +mistake in "mango", and each added one fruit to the list.
      +
      +----
     @@ Documentation/gitmergeconflicts.adoc (new)
      +]
      +----
      +
     -+Here's the same example using `zdiff3`. `zdiff3` takes lines that are
     -+shared between both sides (the `"mango"` line) and moves them outside
     -+the conflicted area. This makes the conflicted area shorter, but the
     -+downside is that it's impossible to tell if `"mango"` was part of the
     -+original list of fruits or not.
     -+
     -+----
     -+FRUITS = [
     -+    "apple",
     -+<<<<<<< HEAD
     -+    "cherry",
     -+||||||| 1c22e48
     -+    "mangoooo",
     -+=======
     -+    "banana",
     -+>>>>>>> add-fruit
     -+    "mango",
     -+    "orange",
     -+]
     -+----
     -+
     ++[NOTE]
     ++================================
     ++`zdiff3` is an alternative to `diff3` that makes the merge conflict
     ++shorter by making it more ambiguous.
     ++================================
      +
      +[[ours]]
      +"OURS" AND "THEIRS"
 2:  d5241eb901 = 2:  8bdbd64ca3 doc: git-merge: link to new merge conflicts guide
 3:  72b1207045 = 3:  34ba85fcad doc: git-rebase: link to new merge conflicts guide
 4:  cfa0a8254a ! 4:  85e117b070 doc: git-revert: link to new merge conflicts guide
     @@ Documentation/git-revert.adoc: both will discard uncommitted changes in your wor
       See "Reset, restore and revert" in linkgit:git[1] for the differences
       between the three commands.
       
     -+If there have been new commits since the reverted commit, there may
     -+be a merge conflict. See linkgit:gitmergeconflicts[7]
     -+(or `git help mergeconflicts`) for a guide to handling merge conflicts.
     ++Reverting a commit may result in a merge conflict.
     ++See linkgit:gitmergeconflicts[7] (or `git help mergeconflicts`)
     ++for a guide to handling merge conflicts.
      +
       OPTIONS
       -------
 5:  62b70e9a02 ! 5:  f99c99f955 doc: git-cherry-pick: link to new merge conflicts guide
     @@ Documentation/git-cherry-pick.adoc: Given one or more existing commits, apply th
       
      -When it is not obvious how to apply a change, the following
      -happens:
     -+When it is not obvious how to apply a change, there may
     -+be a merge conflict. See linkgit:gitmergeconflicts[7]
     -+(or `git help mergeconflicts`) for a guide to handling merge conflicts.
     -+
      +When a merge conflict happens:
       
       1. The current branch and `HEAD` pointer stay at the last commit
     @@ Documentation/git-cherry-pick.adoc: happens:
       
      -See linkgit:git-merge[1] for some hints on resolving such
      -conflicts.
     --
     ++See linkgit:gitmergeconflicts[7] (or `git help mergeconflicts`)
     ++for a guide to handling merge conflicts.
     + 
       OPTIONS
       -------
     - <commit>...::
      @@ Documentation/git-cherry-pick.adoc: $ git cherry-pick -Xpatience topic^  <4>
       SEE ALSO
       --------
 6:  ac77db6762 = 6:  7831b77178 doc: git-pull: link to new merge conflicts guide

-- 
gitgitgadget

  parent reply	other threads:[~2026-10-12 14:53 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 ` Julia Evans via GitGitGadget [this message]
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
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=pull.2237.v3.git.1791816795.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=ben.knoble@gmail.com \
    --cc=git@vger.kernel.org \
    --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.