Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mercurial: how to undo last unpushed commit?

Tags:

mercurial

I have accidentally made a commit to my local repository. To be more specific, I committed changes to lots of files all at once, when I meant to commit them one at a time.

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 in the first place?

I have not pushed or pulled or anything else since the commit.


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.

like image 371
crobar Avatar asked Jul 04 '15 17:07

crobar


People also ask

How do I revert last commit in Mercurial?

If you want to revert just the latest commit use: hg strip --keep -r . Using strip will revert the state of your files to the specified commit but you will have them as pending changes, so you can apply them together with your file to a new commit.

What is hg revert?

hg revert changes the file content only and leaves the working copy parent revision alone.


3 Answers

Based on information from this question:

hg strip --keep --rev .
--keep: do not modify working directory during strip
--rev . (the dot denotes the last commit. read sid0's answer regarding descendants)


For people more familiar with git language, you are looking for git reset --mixed HEAD^

hard which would discard your changes, making your work "disappear" (I assume that is not an option)

soft would undo the commit, but keep previously committed files indexed (that is, tracked)

mixed keeps your changed files in place, but tells the index to undo the commit. in git-speak: git st would say Changes not staged for commit


See also git-reset docs , Difference git reset soft/mixed, git/hg Command equivalence table

like image 161
maosmurf Avatar answered Oct 13 '22 05:10

maosmurf


Ok, I think I've found the answer, it's to enable the strip extension, and use the following command:

hg strip -r -1 --keep

This strips the last revision from the repostiory (the -r -1 bit), and the --keep option means no changes are made to the working copy. So you end up with a working copy exactly as it was just before the commit, and no last commit in the repository.

I'm no mercurial expert, so use at your own risk.

like image 34
crobar Avatar answered Oct 13 '22 04:10

crobar


commenting and elaborating on @crobar's post cause # of characters is not enough.

when doing a local commit (no push) then run hg strip -r -1 --keep, it deletes your previous commit AND preserves your list of files waiting to be committed. basically this is a full undo.

if i use hg strip -r -1 without the --keep, it still deletes your previous commit BUT when i try to list the files to be committed it can't find a change so I wouldn't recommend doing this.

if i do a commit then do a push (to remote) then do hg strip -r -1 --keep, it does exactly what its supposed to do BUT when you do another commit then push, it creates another branch.

I.E. 

o----o----Branch (local)
      \
       \
        --o----o----o----Branch (with previous push)

my source/reference: testing these scenarios

like image 2
Denise Michelle del Bando Avatar answered Oct 13 '22 04:10

Denise Michelle del Bando