rebase to ancestor: just do it

Martin Geisler mg at aragost.com
Mon Sep 12 08:01:55 CDT 2011


Ethan Tira-Thompson <ejt at cmu.edu> writes:

> I often seem to run into the following problem:
>
> I’m working on a smallish feature/bugfix/whatever, made a couple local
> commits but not ready to push it yet.
>
> Then I’m alerted to some other bug/issue and fix that, maybe making a
> couple local commits on that. This secondary issue is independent and
> I want to push it out for other people and go back to my main item.
>
> "Oh crap, I forgot to start a branch and now item 2’s patches are
> based on my item 1 work."
>
> "Well I’ll just rebase item 2 back to the last public changeset... oh
> but rebase doesn’t work on ancestors, wtf."
>
> So now I have to do some hacks with transplanting the first changeset
> of item 2 to get a new head and then rebasing the rest onto that. Same
> effect, but stupidly awkward. Why can’t rebase do this directly, it’s
> a common nuisance that I want to rebase something to a shared
> changeset before pushing. Often that changeset happens to be an
> ancestor, but I don't think that should matter.

It matters since rebase works in terms of merges. When you start with

  ... [a] --- [b] --- [c]
         \
          `-------------- [x] --- [y]

and want to rebase [x] onto [c], then you start by merging [x] and [c]:

  ... [a] --- [b] --- [c] --- [x']
         \                   /
          `-------------- [x] --- [y]

and then you merge [y] and [x']:

  ... [a] --- [b] --- [c] --- [x'] --- [y']
         \                   /       /
          `-------------- [x] --- [y]

You then clean up by deleting the second ancestors of [x'] and [y'] and
delete [x] and [y]:

  ... [a] --- [b] --- [c] --- [x'] --- [y']

By using merges, we get the benefit of using the full merge tool
machinery with three-way merges. We also get the limitation that we
cannot rebase an ancestor since you cannot merge with an ancestor.


Merging with an ancestor makes little sense. Imagine we merge [a] with
[x] in

  ... [a] --- [b] --- [x]

to get

  ... [a] --- [b] --- [x]
         \               \
          `-------------- [x']

Here [x'] == [x] by the normal rules for how three-way merges work. So
the rebase is more a collapse in this case -- not what we want.

-- 
Martin Geisler

aragost Trifork
Professional Mercurial support
http://mercurial.aragost.com/kick-start/


More information about the Mercurial mailing list