"bzr uncommit" equivalent in Mercurial?
Bazaar has a wonderful uncommit command, which simply undoes the last commit. Is there any equivalent in Mercurial?
Edit: Bazaar's uncommit command does not modify files – it removes the last commit and associated data (useful, for example, when you notice too late that there is a typo in a commit message or a file wasn't added that should have been).
$ bzr ci -m "Fixed a proooblem" <-- problem is misspelt $ bzr uncommit ... $ bzr ci -m "Fixed a problem" <-- Exactly as if the first commit was correct.
Maybe hg backout tip? I recommend http://hgbook.red-bean.com/read/finding-and-fixing-mistakes.html for all details about hg backout, how it differs from hg revert, and many related topics, but if I undestand what uncommit does, it does seem exactly equivalent to hg backout tip.
Edit: in a comment you've now clarified you want to "delete history" -- that's hard (unless you're VERY fast on the draw, maybe;-)... per the red-bean book again:
Since Mercurial treats history as accumulative—every change builds on top of all changes that preceded it—you generally can't just make disastrous changes disappear. The one exception is when you've just committed a change, and it hasn't been pushed or pulled into another repository. That's when you can safely use the hg rollback command
So if you just want to try to "make it disappear" (and you're lucky enough that it hasn't yet been pushed or pulled elsewhere), then hg rollback may be a better approach!
You want the hg rollback command, but see below if you're using Mercurial 2.2 or later.
The rollback command will remove the last transaction from your repository. A commit is a transaction, so you can use this as
% hg commit -m 'My elaburate bugfix.' foo.c foo.h % hg rollback % hg commit -m 'My elaborate bugfix.' foo.c foo.h
After the rollback the files will again be seen as modified, and this means that the second commit will store the same changes as the first, but with a better commit message.
Beware: hg rollback is more powerful than a simple "uncommit" function and you can use it to throw away work if you are not careful. To throw away a commit do
$ hg commit -m 'My big and very difficult bugfix' $ hg pull --update $ hg rollback
You've now lost the last commit you made and since you updated the working copy to some other revision, the changes in that commit are gone. So you should only use hg rollback to undo a commit if you're certain that hg commit really was the last command that operated on the working copy.
Also, if you have not given the commit message on the command line, then you cannot just press up-arrow twice to redo the commit after a rollback. However, Mercurial 1.5 and later will save your last commit message in .hg/last-message.txt so that you can always find it again after a rollback.
Mercurial 2.2 has a new --amend flag for hg commit. This let's you amend the last commit with new changes. It simply incorporates the changes listed by hg status into the parent commit, as if you had rolled back and committed again.
Doesn't "hg revert" do that?
From reading the comments, it seems that you want a way to simply do away with the record of the commit without undoing the changes to the file. In Mercurial, there is no automated way of doing this. hg revert is as close as you're going to get.
However, you could do this with a couple manual steps. When you invoke hg revert, its default behavior is to take the files in the changeset you are reverting and rename them as filename.ext.orig, where ext is the original extension of the file. The reverted versions then take on the original filename. So what you could do is run hg revert, delete the files with the original names, and remove .orig from the backup files' names. Then re-commit with your corrected log message. Just don't do this with any revision other than the tip because you'll probably get a lot of changed files and forget which ones belonged in which changeset.
I also would not recommend doing this if you've already pushed your changesets out to a remote repo. Only do this if everything is still only local.
Let me know if you need further explanation. I've had to do this on occasion, so I'm familiar with the process.
There is also the "hg strip" command from the "mq" extension. It is almost exact equivalent of "bzr uncommit". Beware though, when you pushed your errant commit earlier to another repository, it will be recreated with the nearest pull from it.