Subject: Re: [PATCH 4/4] git-rebase -i: New option to support rebase with merges

From: Junio C Hamano <[email-masked]>
Date: Mon, 24 Mar 2008 16:30:57 -0700

I'll extend this topic a bit for the last time, but first a word of
caution.  What I am going to draw is probably not what the current -p
implementation does.  They illustrate what I think should happen.

Again, starting from this topology:

       o---o---o---o---o---Z
      /
     X---Y---A---B
          \       \
           C---D---M---E

and the goal is to rebase your development leading to E on top of the
updated mainline Z.

The earlier example was when you want to end up with this topology:

       o---o---o---o---o---Z---Y'--A'--B'      
      /                         \       \      
     X---Y---A---B               C'--D'--M'--E'
          \       \
           C---D---M---E

In this case, "pick M" cannot be "merge B after pick D".  It needs to
merge in the rewritten B (which is B').

But if you want to end up with this topology:

       o---o---o---o---o---Z---Y'--A'--B'
      /                                 \     
     X---Y---A---B                       M'--E'
          \       \                     /
           C---D---M---E               /
                \                     /
                 `-------------------'

redoing the merge from D when reproducing M' is the right thing to do.

Unfortunately, you cannot express that you would want to rewrite only the
Y--A--B--M--E ancestry from the command line.  We would need a syntax to
do this cleanly first if we want to pursue this.

The "first parent" hack can be used in this case (--first-parent X..E),
but it will probably meet with the same resistance at the philosophical
level (i.e. "merge parents are equal") as the --first-parent option was
criticised for.  But other than that, a sequence to pick Y A B M E in this
order can be presented in the todo list to be edited, and swapping A and M
(for example) should result in this:

       o---o---o---o---o---Z---Y'
      /                         \
     X---Y---A---B               M'--A'--B'
          \       \             /
           C---D---M---E       /
                \             /
                 `-----------'

The existing revision range arithmetic can only come close with "E ^Z ^D"
(or "^D Z..E"), but that would exclude Y as "uninteresting" (because Y is
reachable from D).  You would end up with A--B--M--E.  So even though I am
sympathetic to poeple who complained that the command line parameter to
rebase is different from the log family, using revision range syntax is
not a solution to this.

Just for completeness of the illustration, linealizing form aims to
produce the history like this:

       o---o---o---o---o---Z---Y'--A'--B'--C'--D'--E'
      /
     X---Y---A---B
          \       \
           C---D---M---E

You can freely to reorder anything in the "todo" list without additional
constraints in this form (sequence of "pick" Y, A, B, C, D and E).