Search code examples
mercurialrebase

Rewriting non-linear history in Mercurial / Hg?


I want to hide a topological head (leftover not included into merge of feature branch) without damaging history graph.

The common solution is to merge closing branch commit back to default but this puts extra edge to the history with the length of 10 years of history (damaging hg glog).

I want to rewrite the project history and to include that closing commit before the historical integration merge to default.

Seems https://www.mercurial-scm.org/wiki/RebaseExtension & https://www.mercurial-scm.org/wiki/HisteditExtension extensions operate over the linear history only, unfortunately the history above (and around) the integration merge is a bit messy.

What way is it possible to rewrite non-linear history in Mercurial?

Basically I want to move C in between F and M:

 *B
 |
 *M(erge)
 |\   *C(losing)
 | \ /
A*  *F(eature)

to make it looks like (here C' M' B' are only changing hashes):

  *B'
  |
  *M'(erge)
  /\ 
A*  *C'(losing)
    |
    *F(eature)

Solution

  • If you haven't already pushed, so that no one else has M or B, then you can:

    1. Update to A
    2. Merge with C, creating M' (I don't see a need for a C')
    3. Rebase or graft B, creating B'
    4. Strip, or prune M and B -- or just ignore them as long as they are secret phase
    5. Push

    If things have already been pushed than you can't do anything destructive to M or its descendants. But steps up through #4 will be fine.

    (Unless your team is using https://www.mercurial-scm.org/wiki/ChangesetEvolution)