57

I want to completely delete a Mercurial commit as if it was never entered in the repository and move back to my prior commit.

Is this possible?

Gangnus
  • 24,044
  • 16
  • 90
  • 149
mdp
  • 571
  • 1
  • 4
  • 3
  • Duplicate of http://stackoverflow.com/questions/2338986/is-there-any-way-to-delete-local-commits-in-mercurial - see in particular answer http://stackoverflow.com/a/6549478/8479 – Rory Nov 05 '12 at 23:02
  • Possible duplicate of [Is there any way to delete local commits in Mercurial?](https://stackoverflow.com/questions/2338986/is-there-any-way-to-delete-local-commits-in-mercurial) – StayOnTarget Oct 24 '18 at 11:41

9 Answers9

33

If it was your last commit and you haven't pushed it anywhere, you can do that with rollback. Otherwise, no. Not really. Time to change your passwords.

Edit: It has been pointed out that you can clone from an older revision and merge in the changes you want to keep. That's also true, unless you have pushed it to a repo you don't control. Once you push, your data is very likely to be very hard to get back.

nmichaels
  • 49,466
  • 12
  • 107
  • 135
  • 1
    haha I have accidentally done that (there goes my ssh private key) – Adam Gent Feb 23 '11 at 00:27
  • What about changing the phase to secret if you have not pushed the revision? – 1nfiniti Mar 22 '13 at 06:29
  • @mikeyUX: This answer was written before 2.1 came out, but changing the phase to secret doesn't actually delete the changeset; it just prevents you from seeing it in `hg outgoing` or sharing it with another repository. Changing the phase to secret, then cloning will do roughly the same thing as my edit suggests. I'd use histedit or mq before doing that though. – nmichaels Mar 27 '13 at 20:19
  • Using the HisteditExtension you can drop a commit. The feature might be newer than this accepted answer. – Jon Davis Jul 26 '14 at 19:52
  • @stimpy77: Histedit will still not help if you've pushed or someone has pulled. If neither of those have happened then you're right. Histedit, mq, rollback, and strip will all obliterate changesets if you ask them nicely. – nmichaels Jul 29 '14 at 14:53
30

You can try to remove mq info about your commit.

  • For this you need to go File->Settings->Extensions.
  • There check mq and restart gui.
  • After that just right click on unneeded commit and ModifyHistory->Strip
Stanislav
  • 325
  • 3
  • 2
13

To edit the history I would use the Histedit Extension extension.

 hg histedit 45:c3a3a271d11c

However keep in mind this only makes sense in a situation where you have not yet pushed the commits to the public repository, you own the public repository and/or you can account for all the clones out there. If you receive the following error:

abort: can't rebase immutable changeset 43ab8134e7af

It means that Mecurial thinks this is a public changeset (see phases) that has already been pushed - you can force it to be a draft again doing:

hg phase -f -d 45:c3a3a271d11c
rodolfojcj
  • 863
  • 7
  • 10
Daniel Sokolowski
  • 11,982
  • 4
  • 69
  • 55
7

I encounter this fairly often. I make a commit and then pull to push. But then there is something incoming that makes my newly made commit unnecessary. A plain hg rollback isn't enough because it only undoes the pull...

This is the thing to do:

hg strip <rev>

Things are painless when you don't push your changesets anywhere.

mike3996
  • 17,047
  • 9
  • 64
  • 80
6

If it's more than one commit and/or you already pushed it somewhere else, you can clone your repository and specify the last changeset that should be cloned.

See my answer here how to do this:
Mercurial: Fix a borked history

If you only committed locally and didn't push, you can just create a clone locally (as described in my link) and you're done.

If you already pushed to some remote repository, you would have to replace that with your clone.
Of course it depends if you are able (or allowed) to do this.

Community
  • 1
  • 1
Christian Specht
  • 35,843
  • 15
  • 128
  • 182
5

You can use "hg backout" to do a reverse merge basically. All options are discussed in the freely available book "Mercurial: The Definitive Guide":

http://hgbook.red-bean.com/read/finding-and-fixing-mistakes.html

Jeremy Whitlock
  • 3,808
  • 26
  • 16
  • I realize my suggestion doesn't delete the commit but the link does talk about all options, including the "hg rollback" option nmichaels suggested. – Jeremy Whitlock Feb 22 '11 at 22:48
  • Generally I like this solution. It's alright to admit your mistakes and keep a history of your bad commits, as well as the fact that you backed them. – Kamil Kisiel Feb 23 '11 at 02:55
3

If using tortoise you can use modify history > strip...

1

Yes. Unless I am mistaken, as of v2.3 (rel. 2012/08/01) you can use the HisteditExtension with a drop command to drop a commit, along with strip or backout to remove changes.

A simple Google search on the feature: https://www.google.com/webhp#q=histedit+drop

Jon Davis
  • 6,562
  • 5
  • 43
  • 60
1

In 2022 I do use evolve extension. It is one of the best extensions for this purpose.

To prune unwanted changeset, if you for example did a quick hack to get the code working:

$ echo 'debug hack' >> file1.c
$ hg commit -m 'debug hack'

Now you have a proper patch you can do hg prune .:

$ hg prune .
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
working directory is now at 2a39221aaebb
1 changesets pruned

If you push the change to the remote repository you will find only obsolescence markers:

$ hg push
searching for changes                          
no changes found                               
remote: 1 new obsolescence markers             

To check the changes to your local repo you can pull from the remote one:

$ hg pull                            
pulling from ssh://userid@server/repo
searching for changes      
no changes found
tukan
  • 17,050
  • 1
  • 20
  • 48