0 0 0 0


I have a simple issue. I have accidentally made a commit to my local repository. I have not pushed or pulled, or anything else since the commit. How do I undo this commit, and get my working copy back to the state it was before the commit, so I can do what I should have done?

You may suspect this is a duplicate, so I will explain why the following questions are different, or do not answer my question:

Mercurial undo last commit

An answer to this one states that you can do this with hg commit --amend, but does not explain how or give an example of doing this. The mercurail help does not spell it out for me either.

How do you "rollback" last commit on Mercurial?

States to use hg rollback. This command is apparently deprecated, I tried using it anyway, but I got the messge: no rollback information available. A shame this doesn't work as this would be a really intuitive way to achieve what I want.

Edit 1

To be more specific, I committed changes to lots of files, when I really want to commit them one at a time. How do I go back so that I can do this?

Best Answer:

What I'd do in this situation is make a new branch that has the changes I want before I ever thought about removing the bad change-set. So in this case I'll need to go back to the revision before I made the bad commit, re-do my changes and then make multiple commits, one for each file.

Step by step:

1) Go back to before the bad commit.

% cd <top of repo>
% hg log -l 5
<identify the last good revision>
% hg update -r <last good revision number>

2) Remake the changes: I'd get a patch which describes the changes I want, and apply it to the tree. (I'm assuming tip currently points to where we started)

% hg diff -r .:tip | patch -p1
patching file a/b/c/d
patching file a/b/e/f

3) Make new commits: We're now back at the state before you made the commit you wanted to split up. Do hg status and look at the modified files, make sure everything is as you expect. At this point you can either commit the files one by one by naming them on the command line, or use an extension like record or crecord to interactively select them.

% hg commit a/b/c/d
% hg commit a/b/e/f


% hg crecord
<select files in UI>
% hg crecord
<select files in UI>

You'll end up with a repo that looks like this:


Where B is the old bad commit, and T is the new tip of the repo. If you want to then make that branch as closed, so it doesn't show up in logs / etc, you can...

% hg update -r <revision B>
% hg commit --close_branch
% hg update -r tip

If you want to remove it completely, you can strip it.

% hg strip -r <revision B>

Either way, your log will look like nothing ever happened.

Copyright © 2011 Dowemo All rights reserved.    Creative Commons   AboutUs