Martin von Zweigbergk <> writes:

> do you agree
> that 'rebase --onto does not re-apply patches in onto' is desirable?

This depends on how you look at --onto.  Recall the most typical and
the original use case of rebase:

                               A'--C' your rebased work
  ---o---o---o---F---B'--o---T master
     ^            \
     v1.7.12       A---B---C your work

You could view "git rebase master" as a short-hand for

        $ git rebase --onto $(git merge-base master HEAD) master


        $ git rebase --onto F master

If you view "onto" that way, you would certainly do not want to see
B replayed on top of T, which already contains another replay of B
in its history.

The intended use case for "--onto", however, is primarily to replay
a history to older base, i.e.

       A'--B'--C' your rebased work
  ---o---o---o---F---B'--o---T master
     ^            \
     v1.7.12       A---B---C your work

        $ git rebase --onto v1.7.12 master

which is a moral equivalent of

        $ git checkout v1.7.12
        $ git cherry-pick A B C ;# or git cherry-pick master..HEAD

You could argue that you can compute the patch equivalence between
the commits in "onto..master" and commits in "master..HEAD" and
filter out the equivalent commits to reach the expected results in
either cases, and at the logical level, it certainly will produce
the result I showed in the above illustrations.

But there are two flaws in such an argument.

The "replay to an updated base" case (i.e. without "--onto") expects
to see duplicated commits in the updated history.  That is the only
reason you would want to rebase---otherwise you can keep the old
fork point and keep polishing your work and merge when it is truly
ready.  More importantly, the old master (the fork point F) and
updated master (the current tip T) are expected to have some
ancestry relationship between them.  For these reasons, running the
equivalent of "git cherry" to filter commits with patch equivalence
makes perfect sense.

On the other hand, when the user replays to an older base, she has
some idea what constitutes "a series" that she is replaying (i.e.
"$(git merge-base master HEAD)..HEAD").  It smells to go against the
user's world model if the command silently filtered commits by patch
equivalence.  The user wanted to replay A, B and C in that case, and
it is better to stop the process and make her inspect the history
when the older base happened to have a patch-equivalent commit that
would cause a conflict. That would give her a chance to assess the
situation, instead of silently dropping some of these three commits
that she initially thought constitutes the series and ending up with
a series with only two commits.

Besides, the whole point of a separate "onto" is to allow the user
to specify a commit that does not have a straightforward ancestry
relationship with the bottom of the series (i.e. either "master" or
"F"), and computation of patch equivalence is expected to be much
higher.  Given that it is unlikely to find any match, it feels
doubly wrong to always run "git cherry" equivalent in that case.

So I dunno, as I can argue both ways.

My gut feeling is that "git rebase master" and "git rebase --onto F
master" should not be identical in this regard and an explicit
"onto" should omit the patch equivalence filtering, but I can be
persuaded otherwise with good arguments.

> How about 'rebase --root is not a no-op'?

  ---o---o---o---F---B'--o---T master
     ^            \
     v1.7.12       A---B---C your work

If "git rebase F" when you are at C in the above illustration
(reproduced only the relevant parts) is a no-op (and I think it
should be), "git rebase --root" in the illustration below ought to
be as well, no?

                 F---B'--o---T master
                   A---B---C your work
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to
More majordomo info at

Reply via email to