Subject: Re: [PATCH] docs: Clarify what git-rebase's "--preserve-merges" does

From: Junio C Hamano <[email-masked]>
Date: Mon, 30 Mar 2015 13:23:49 -0700

Junio C Hamano <[email-masked]> writes:

>> Ignoring a merge sounds like dropping the merge commit and all side
>> branches it merges from history.
>
> ... Yes to _some_ people (including you, but not me).  And that is
> why we are trying to improve the text in the documentation, no?

Let's try this again as I do not think there is no need to argue in
the end.

We agree that this is a good patch:

diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index d728030..47984e8 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -362,7 +362,9 @@ default is `--no-fork-point`, otherwise the default is `--fork-point`.
 
 -p::
 --preserve-merges::
-	Instead of ignoring merges, try to recreate them.
+	Recreate merge commits instead of flattening the history by replaying
+	commits a merge commit introduces. Merge conflict resolutions or manual
+	amendments to merge commits are not preserved.
 +
 This uses the `--interactive` machinery internally, but combining it
 with the `--interactive` option explicitly is generally not a good

The primary reason is "ignoring merges" can be read in two ways.

 - Some people, including the ones who wrote the original text (and
   also those who haven't complained to the original text since 2008
   because their reading of the phrase was the same as those who
   wrote it), read it as "We will normally replay what appears in
   the output from 'git log --no-merges', losing what was merged
   where into what.  This option instead keeps the shape of the
   history by considering where the merge commits sit in the
   original history".

 - It can however be read in a different way, namely, "We will
   replay what appears in 'git log --first-parent --no-merges'
   output, ignoring all the side branches".  Some other people,
   including you, find that inconsistent with what is actually
   implemented as a normal rebase.

And we agree the updated text is a good change, because it does not
say "ignore merge" anywhere to invite such a confusion.

I am only reacting to your description to justify that change, which
was:

> Ignoring a merge sounds like ignoring the changes a merge commit
> introduces altogether, as if the merge commit was skipped or dropped from
> history. But that is not what happens if "-p" is not specified.

And we agree that the first part of the sentence, up to
"... altogether", is good.

I am saying "as if" part is reintroducing the confusion.

    as if the merge commit was skipped or dropped from history.

To those who did not interpret the existing "ignoring merges", which
meant to be read as "replay the output of 'log --no-merges'
sequencially", the above exactly says "replay the output of 'log
--no-merges'".  That is the reason why they were happy with the
current text, without seeing how it can be read differently.

To them (including me), the justfication is saying "... sounds like
X, as if Y, but it is wrong" using Y that is completely opposite of
X, even they would agree that X is a wrong interpretation caused by
a non-optimal phrasing.

That is why I suggested to avoid "merge commit was skipped or
dropped" in the description and instead say "as if the side branch
that was merged was skipped or dropped".

The following may be agreeable to both camps of people, those who
read "ignoring merge" to mean "log --no-merges" and those who read
it to mean "log --first-parent --no-merges", I would think.

-- >8 --
From: Sebastian Schuberth <[email-masked]>
Date: Mon, 30 Mar 2015 11:29:46 +0200
Subject docs: clarify what git-rebase's "-p" / "--preserve-merges" does

Ignoring a merge can be read as ignoring the changes a merge commit
introduces altogether, as if the entire side branch the merge commit
merged was removed from the history.  But that is not what happens
if "-p" is not specified.  What happens is that the individual
commits a merge commit introduces are replayed in order, and only
any possible merge conflict resolutions or manual amendments to the
merge commit are ignored.

Get this straight in the docs.

Also, do not say that merge commits are *tried* to be recreated. As that is
true almost everywhere it is better left unsaid.

Signed-off-by: Sebastian Schuberth <[email-masked]>
---
 Documentation/git-rebase.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index d728030..47984e8 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -362,7 +362,9 @@ default is `--no-fork-point`, otherwise the default is `--fork-point`.
 
 -p::
 --preserve-merges::
-	Instead of ignoring merges, try to recreate them.
+	Recreate merge commits instead of flattening the history by replaying
+	commits a merge commit introduces. Merge conflict resolutions or manual
+	amendments to merge commits are not preserved.
 +
 This uses the `--interactive` machinery internally, but combining it
 with the `--interactive` option explicitly is generally not a good