NOTE: You almost certainly don’t want to do anything in this article. I wrote this in 2008; Mercurial has improved a lot since then. While everything’s still accurate (as far as I know), using MQ is pain-ridden and unnecessary. Instead, you should use histedit (which is bundled with Mercurial) or the evolve extension (which is not yet, but may be soon). Either will get you to the same place, but they’re both easier, safer, and more powerful than MQ—a rare triple. That said, if you’re curious how things used to work, or if you can’t use a modern version of Mercurial, read on.
Last night, I realized that I had accidentally made some commits to one of my Mercurial repositories without an email address set, meaning that they all showed up as benjamin@localhost
. Since the repository’s private, and I wasn’t worried about destructively rewriting history, I wondered, can I fix this using mq
?
The answer was a resounding, “yes.”
First, let’s bring the entire history into mq
, and save the result so that we have something to go back to in case we screw up:
~/code/bqb$ hg qimport -r 0:tip
~/code/bqb$ hg qci -m "Before address change"
Next, because we’re about to rewrite the patches themselves, we’ll pop off all of the patches:
~/code/bqb$ hg qpop -a
at which point we can safely go and make our changes with some simple sed
magic.
~/code/bqb$ cd .hg/patches
~/code/bqb/.hg/patches$ sed -i -e "s/@localhost/@bitquabit.com/" *.diff
~/code/bqb/.hg/patches$ hg diff
Everything looks okay, so it’s time to reapply the patches:
~/code/bqb/.hg/patches$ cd ../..
~/code/bqb$ hg qpush -a
and convert them back into changesets.
~/code/bqb$ hg qdelete -r qbase:qtip
Did it work?
~/code/bqb$ hg log | grep '@localhost'
~/code/bqb$
Yep. We’re all set.
A couple of things to keep in mind if you do this:
- Just to state the obvious, you’re rewriting history. You will no longer be able to interact with repositories made before the rewrite. This means you should never try the above stunt on a repository you’ve shared with others. (Well, mostly. If you only run the initial
qimport
on changes you’ve not yet pushed out—rather than on the entire repository, as I did—you’re fine. Just be careful.) - Make very sure you’ve set Mercurial to use
git
-style patches, or you will unwittingly annihilate blank and binary files when you convert your changesets to patches. If you’ve not yet done so, edit your~/.hgrc
so that-g
is passed by default toqimport
andqrefresh
. - Remember that whenever working with
mq
, you have the potential to completely lose your history. Be careful. Usehg qci
to back up known-good patch states early and often.
Want to comment on this post? Join the discussion! Email my public inbox.