Backing out multiple consecutive changesets in Mercurial

As landing multiple patches together has become common practice on mozilla-central, we’ve started a semi-official policy of requiring people to back out all of the changesets in their push if something breaks.  This is a good thing, because mozilla-central is not a very good place to test bustage fixes, and it helps the tree to get to a good state very soon.

However, when you want to back out multiple patches in a push, backing them out individually using hg backout is a real pain, it basically means that you have to merge N times if you have N patches to back out.  There is an easy way to back out multiple patches in Mercurial though, and I’ve been asked about this by people in IRC several times recently, so I figured I’d blog about it since people seem to need it.

Let’s say you’ve pushed N consecutive changesets, with the first one having the changeset ID cset1 and the last one having the changeset ID csetN.  You also need to know the the ID of the parent changeset for cset1.  Let’s call that csetP.  To back out everything from cset1 to csetN (inclusive), you should do something like this:

hg pull # make sure you have a recent tree
hg update csetN # update to the last changeset in the range
hg revert -a -r csetP # revert to the parent of the first changeset
hg commit -m "Back out bug xxxxxx, bug yyyyyy, ..." # commit the backout
hg merge # if csetN is the repository's tip, merging is not necessary
hg commit -m "Merge backout, a=bustage fix" # commit the merge
hg push # push the backout
Posted in Blog Tagged with: , ,
7 comments on “Backing out multiple consecutive changesets in Mercurial
  1. Thanks a lot – helped me out of a tight spot and I was able to avoid doing multiple backouts and merges

  2. This is great! For bonus points: if you’re using a patch queue, you can skip the “merge” changeset (assuming no manual merging is required), diverging from ehsan’s instructions at step 4:

    1. (same)
    2. (same)
    3. (same)
    4. hg qnew my_backout -f -m “Back out bug xxxxxx, bug yyyyyy, …” # Save the backout as a mq patch
    5. hg qpop # Pop the backout
    6. hg up -r default # Update to tip
    7. hg qpush # Apply the backout
    8. hg qfin my_backout # Take the backout out of your queue for pushing
    9. hg push

    (I haven’t tested the above commands exactly, so they might not be exactly correct, but they’re basically what you’d want.)

  3. Or you could just rebase…

  4. [...] Backing out multiple consecutive changesets in Mercurial | Ehsan … [...]

  5. hg pull -u makes no sense if you’re going to hg update anyway…

  6. Ehsan Akhgari says:

    True.  I edited the article to include this correction.

  7. [...] thing about this method is that there’s no merge required. See also, Ehsan’s recent post on the [...]