Disclaimer: This kind of trickery can easily break your repository and totally annoy your collaborators. So take backups, butter up your friends, and consider yourself warned.. I take no responsibility for your issues should anything go wrong, and in fact this message will self-destruct in 10 seconds..
Anyway, the main point is just to document this for myself the next time I fail. I committed some stuff to a project in Google Code and noticed after a laptop change I had forgotten to set the username for mercurial. By default it grabs this information from the OS and network, which being paranoid, I did not wish to include in the public history. Next time I should just set the HGUSER environment variable.
But Mercurial does not let me “undo” pushed commits or modify them. And I had done two of them before noticing that I forgot to re-configure the username on the “new” laptop.
Addressing this is discussed here: http://code.google.com/p/support/wiki/MercurialFAQ. But it took me a while to get it figured out and to go ahead and just try it. So here is what worked (for me):
As noted here: http://mercurial.selenic.com/guide/#removing_history, we start with creating a fresh clone of the repository but without the commits we wish to modify. So assume we are at revision 202 and wish to modify the commit information for 201 and 202. Assume our project is named “gummybears” and is located in a directory with this name. We open terminal/command prompt in the directory above “gummybears”. We do this to get ourselves revision 200 in directory “gummybears-fix”:
hg clone -r 200 gummybears gummybears-fix
Then we want to get the changes that were present in revisions 201 and 202 but with a different username.
To do this, we issue the following set of commands (again from http://mercurial.selenic.com/guide/#removing_history):
cd gummybears hg export 201 > ..\changes201.diff hg export 202 > ..\changes202.diff
Now we have the revision 201 and 202 changes in the files changes201.diff and changes202.diff. By importing these to the “gummybears-fix” directory we can get a new versions of the repository with the naughty commits re-applied. But if we just do this, they will be re-applied with the bad username as before. So open up your favourite text editor and load the two “.diff” files. On the top is the “Username” field. Edit the value to your liking to not make the same mistake again.
Now we issue the following commands
cd gummybears-fix hg import ..\changes201.diff hg import ..\changes202.diff
And then we go for the step 4, profit. Go to Google Code, under project administration reset your repository. This will completely nuke everything so just be sure you understand what you are doing. After this rename “gummybears” to “gummybears-old” and rename “gummybears-fix” to “gummybears”. Probably this is not necessary but paranoia is good. Trust me, I know what I am doing (yeah right, boom). Finally, enter your new “gummybears” directory and type the following command
And then.. profit! hah, or so we wish. Anyways, your repository should now be fixed, with all the history intact and the usernames changed to protect the innocent. You can probably apply this to do other changes other than username too if you have the courage..
Oh yeah, then your still have to remove the old modified “commits” from your computer where you did the commit if this is not the one where you did these changes. Try this:
This does not actually work for me, but maybe you get a better experience. In any case, I am cloning a fresh set just to be sure..