Subject: Re: [PATCH] Documentation/git-rebase.txt: fix -f description to match actual git behavior.

From: Junio C Hamano <[email-masked]>
Date: Fri, 15 Aug 2014 10:51:45 -0700

Sergey Organov <[email-masked]> writes:

>> ...
>> diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
>> index 2a93c64..f14100a 100644
>> --- a/Documentation/git-rebase.txt
>> +++ b/Documentation/git-rebase.txt
>> @@ -316,11 +316,8 @@ which makes little sense.
>>  
>>  -f::
>>  --force-rebase::
>> -	Force the rebase even if the current branch is a descendant
>> -	of the commit you are rebasing onto.  Normally non-interactive rebase will
>> -	exit with the message "Current branch is up to date" in such a
>> -	situation.
>> -	Incompatible with the --interactive option.
>> +	Force a rebase even if the current branch is up-to-date and
>> +	the command without `--force` would return without doing anything.
>>  +
>>  You may find this (or --no-ff with an interactive rebase) helpful after
>>  reverting a topic branch merge, as this option recreates the topic branch with
>
> I dig more into it, and that's what I came up with, using some of your
> suggestions as well.
>
> Please notice new text on essential interaction with --preserve-merges.
>
> I also thought about "Force the rebase that would otherwise be a no-op",
> and while it is future-changes-agnostic indeed, it doesn't actually
> explain anything, so I put some explanation back.

A sentence "--force has no effect under --preserve-merges mode" does
not tell the readers very much, either and leaves them wondering if
it means "--preserve-merges mode always rebases every time it is
asked, never noticing 'ah, the history is already in a good shape
and there is no need to do anything further'" or "--preserve-merges
mode ignores --force and refuses to recreate the history if the
history is in the shape the mode deems is already desirable."

I think the root cause of the issue we share in this thread, when
trying to come up with an improvement of this part, is that we are
trying to put more explanation to the description of --force, but if
we step back a bit, it may be that the explanation does not belong
there.  As far as the readers are concerned, --force is about
forcing a rebase that would not otherwise be a no-op, but the real
issue is that the condition under which a requested rebase becomes a
no-op, iow, "the history is already in the desired shape, nothing to
do", is different from mode to mode, because "the desired shape" is
what distinguishes the modes.  Preserve-merge rebase may think that
a history that is descendant of the "onto" commit is already in the
desired shape while plain-vanilla rebase does not if it has a merge
in between, for example.

The sentence that follows "Otherwise" in this version encourages the
readers to be in a wrong mind-set that rebase is only about "making
the branch a descendant of the 'onto' commit", which isn't the case.

The desired outcome depends on the mode (and that is why there are
modes), and not saying that explicitly will only help spread the
confusion, I am afraid.  Isn't it a better solution to explain what
that no-op condition is for the mode at the place in the document
where we describe each mode?

E.g. under "--preserve-merges" heading, we may say "make sure the
history is a descendant of the 'onto' commit; if it already is,
nothing is done because there is no need to do anything" or
something along that line.  The description for the plain-vanilla
rebase may say "flatten the history on top of the 'onto' commit by
replaying the changes in each non-merge commit; if the history is
already a descendant of the 'onto' commit without any merge in
between, nothing is done because there is no need to".

That would make description of the modes more understandable, too.
The users can read what kind of resulting history they can get out
of by using each mode in one place.

Hmm?

> -- >8 --
>
> From: Sergey Organov <[email-masked]>
> Date: Tue, 12 Aug 2014 00:10:19 +0400
> Subject: [PATCH] Documentation/git-rebase.txt: fix -f description to match
>
> "Current branch is a descendant of the commit you are rebasing onto"
> does not necessarily mean "rebase" requires "--force". Presence of
> merge commit(s) makes "rebase" perform its default flattening actions
> anyway.
>
> Signed-off-by: Sergey Organov <[email-masked]>
> ---
>  Documentation/git-rebase.txt | 9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
> index 2a93c64..9153369 100644
> --- a/Documentation/git-rebase.txt
> +++ b/Documentation/git-rebase.txt
> @@ -316,11 +316,10 @@ which makes little sense.
>  
>  -f::
>  --force-rebase::
> -	Force the rebase even if the current branch is a descendant
> -	of the commit you are rebasing onto.  Normally non-interactive rebase will
> -	exit with the message "Current branch is up to date" in such a
> -	situation.
> -	Incompatible with the --interactive option.
> +	If --preserve-merges is given, has no effect. Otherwise forces
> +	rebase even if the current branch is a descendant of the commit
> +	you are rebasing onto and there are no merge commits among
> +	those to be rebased.
>  +
>  You may find this (or --no-ff with an interactive rebase) helpful after
>  reverting a topic branch merge, as this option recreates the topic branch with