Search code examples
version-controlmercurial

How to split a Mercurial chain into independent changes merging at the tip


I started working on a commit, let's call it C

master - C (tip)

However, after a series of splits, I ended up with something like

master - A - B - C (tip)

As it turns out, A and B are independent of each other but C depends on both. Is there a way to split this chain in such a way that I can work on A and B independently:

master - A - merge - C (tip)
      \     /
        - B 

Solution

  • You can do this as long as you haven't pushed your changes yet. If you've pushed and other people have replicated the original series of A-B-C changesets you can't easily undo that.

    There are in fact several ways to do this... this is what I think is the most straightforward.

    STEP 1:

    hg up master

    hg revert -r B

    hg commit (consider this B2)

    So now B2 looks like the original B but follows master instead of A. The original B still exists for now:

    master - A - B - C
           \
             B2
    

    STEP 2:

    hg merge -r A

    hg revert -r C

    hg commit (consider this C2)

    And now you have:

    master - A  - B - C
           \    \
             B2 - C2
    

    STEP 3:

    Finally clean up your original unwanted B & C:

    hg strip B

    Note that strip is technically an extension so you might have to enable it in your hgrc.

    Comment - in step 1 you could use also graft instead of revert to replicate B to B2. I tend to use revert because it is more versatile but it does require an explicit commit that graft would avoid.