Mercurial: roll back an "hg commit --amend".
Asked Answered
F

6

34

I accidentally did a "hg commit --amend" instead of just a commit. How can I roll back the commit to before the amend?

Friede answered 22/5, 2013 at 16:49 Comment(0)
G
-4

NOTE: This answer is now deprecated. See the answer from @Sorina Sandu instead.


See hg help commit, where it says:

The --amend flag can be used to amend the parent of the working directory with a new commit that contains the changes in the parent in addition to those currently reported by "hg status", if there are any. The old commit is stored in a backup bundle in ".hg/strip-backup" (see "hg help bundle" and "hg help unbundle" on how to restore it).

Grum answered 22/5, 2013 at 18:46 Comment(3)
Please improve this answer by explaining what steps need to be done after the unbundle to actually get to the unamended commit.Kassab
@akuhn, I think it's hg merge and then hg commit -m 'message_for_the_last_commit', but it messes the history a bit.Monostome
Generally speaking, you'll either just amend the newly unbundled tip commit itself, so that you can give it a meaningful error message, or you'll do as @Monostome suggested and merge. In many cases, you'll end up wanting the commit message of the former tip (left in place by hg unbundle) as the message used with the new tip.Argyres
P
65

You can use hg reflog (from the journal extension) and hg reset <hash>.

hg reflog -v

should give something like:

<old-hash> -> <new-hash> <user> <timestamp>  commit --amend <some-path>

if that is the amend you want to revert, just use:

hg reset <old-hash>

The commit will be reverted to what is previously was and the changes that were amended should now be uncommitted changes (check using hg status and hg diff).

Palette answered 8/7, 2015 at 20:24 Comment(9)
this is a correct answer. mercurial does support reflog and resetGalagalactagogue
@JacobKrall This works for me perfectly with Mercurial.Refund
@Refund I think you have enabled an extension providing the reflog and reset commands. Maybe the experimental journal extension?Footman
@YiZhu what extensions do you have?Footman
@RishabhMarya what extensions do you have?Footman
@JacobKrall I double checked and the extension journal is indeed enabled. You are right if that extension provides such commands. To be honest, I don't know what will happen I uninstalled the extensions.Refund
As of Nov 2017, "This extension is distributed with Mercurial as experimental."Cystocele
Maybe I'm missing something, and the journal extension Wiki page does indeed mention these commands, but the actual extension as of Mercurial 4.5 only contains the hg journal command. I'm confused.Beckiebeckley
as of 2019 it looks like neither reflog or reset are recognised when the journal extension is enabled, nor are they mentioned in the journal extension wiki pageCreon
M
15

If your version of Mercurial is new enough, I believe you should be able to use the hg unamend command from the uncommit extension that ships with Mercurial. This may require that obsolescence markers are enabled, I'm not sure.

  1. Enable the uncommit extension, add this to your ~/.hgrc:

    [extensions]
    uncommit =
    
  2. Actually run the unamend:

    hg unamend
    
Mangrum answered 8/2, 2019 at 20:22 Comment(1)
Note that a new commit will be created and only the content will be rolled back (history keeps moving forward).Older
C
5
  1. Find the latest saved backup in .hg/strip-backup directory
  2. hg unbundle .hg/strip-backup/<latest backup>
  3. Now you should have two heads - one with the amended commit, other one with two commits (first one - old commit before amending, second one caled: "temporary amend commit for (old commit hash)".
  4. if you have histedit extension, you can do hg histedit on it in order to change it (e.g. select edit in order to achieve a state just before the commit, i.e. when you can see all changes using hg diff).

Don't forget to strip the old head.

Congregation answered 29/7, 2016 at 5:42 Comment(0)
E
1

It's 2022, and my attempts to use hg unamend have not worked. histedit is too clunky for my purposes, but the solution proposed by mariu52 elsewhere on this page can easily be adapted to work without histedit. It relies on the -k option of the strip subcommand.

In a nutshell:

  1. Find the latest saved backup in the .hg/strip-backup/ directory
  2. Run hg unbundle .hg/strip-backup/<latest backup> where <latest backup> signifies the full filename.
  3. Run hg heads and note the rev number corresponding to the amendment. Let's call this $AMENDREV; this is the rev number we will strip in the next step.
  4. Run hg strip -k --rev $AMENDREV

Using the -k option in the strip command is critical.

WARNING: this procedure will in effect erase the memory of any add or remove commands that were pending when the amend command was executed.

For example, in the transcript below, the hg add file2 command is effectively forgotten after the strip command is executed.


For clarity, here's a transcript based on the above recipe.

$ mkdir tmp ; cd tmp
$ ls
$ echo 1 > file1
$ echo 2 > file2
$ hg init
$ ls
file1   file2
$ hg add file1
$ hg commit -m 'one file'
$ hg add file2
$ hg amend -m 'amendment'
saved backup bundle to /tmp/tmp/.hg/strip-backup/d332ee829c21-5a5f23b0-amend.hg
$ hg unbundle -u .hg/strip-backup/d332ee829c21-5a5f23b0-amend.hg
adding changesets
adding manifests
adding file changes
added 1 changesets with 0 changes to 1 files (+1 heads)
new changesets d332ee829c21 (1 drafts)
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
updated to "1a445f3252eb: amendment"
1 other heads for branch "default"
$ hg heads
1[tip]:-1   d332ee829c21   2022-11-09 01:55 -0500   peak
  one file

0   1a445f3252eb   2022-11-09 01:55 -0500   peak
  amendment

$ ls
file1   file2
$ hg strip -k -r 0
saved backup bundle to /tmp/tmp/.hg/strip-backup/1a445f3252eb-bfaab5ec-backup.hg
$ ls
file1   file2
$ hg list
r0:  peak tip 2022-11-09 01:55 -0500
        one file
    file1
$
Energumen answered 9/11, 2022 at 7:5 Comment(0)
V
1

hg unamend part of Mercurial 4.5 (2018-02-01).

Valero answered 26/1, 2023 at 19:17 Comment(0)
G
-4

NOTE: This answer is now deprecated. See the answer from @Sorina Sandu instead.


See hg help commit, where it says:

The --amend flag can be used to amend the parent of the working directory with a new commit that contains the changes in the parent in addition to those currently reported by "hg status", if there are any. The old commit is stored in a backup bundle in ".hg/strip-backup" (see "hg help bundle" and "hg help unbundle" on how to restore it).

Grum answered 22/5, 2013 at 18:46 Comment(3)
Please improve this answer by explaining what steps need to be done after the unbundle to actually get to the unamended commit.Kassab
@akuhn, I think it's hg merge and then hg commit -m 'message_for_the_last_commit', but it messes the history a bit.Monostome
Generally speaking, you'll either just amend the newly unbundled tip commit itself, so that you can give it a meaningful error message, or you'll do as @Monostome suggested and merge. In many cases, you'll end up wanting the commit message of the former tip (left in place by hg unbundle) as the message used with the new tip.Argyres

© 2022 - 2024 — McMap. All rights reserved.