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:

  1. hg pull # make sure you have a recent tree
  2. hg update csetN # update to the last changeset in the range
  3. hg revert -a -r csetP # revert to the parent of the first changeset
  4. hg commit -m "Back out bug xxxxxx, bug yyyyyy, ..." # commit the backout
  5. hg merge # if csetN is the repository's tip, merging is not necessary
  6. hg commit -m "Merge backout, a=bustage fix" # commit the merge
  7. hg push # push the backout

Trackback URL for this post:

http://ehsanakhgari.org/trackback/118

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Pingback

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

hg pull -u makes no sense if

hg pull -u makes no sense if you're going to hg update anyway...

Re: hg pull -u makes no sense if

True.  I edited the article to include this correction.

Pingback

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

Or, using patch-queues...

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.)

Or you could just rebase...

Or you could just rebase...