I accidentally did a "hg commit --amend" instead of just a commit. How can I roll back the commit to before the amend?
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).
hg merge
and then hg commit -m 'message_for_the_last_commit'
, but it messes the history a bit. –
Monostome 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 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
).
reflog
and reset
commands. Maybe the experimental journal
extension? –
Footman 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 hg journal
command. I'm confused. –
Beckiebeckley reflog
or reset
are recognised when the journal extension is enabled, nor are they mentioned in the journal extension wiki page –
Creon 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.
Enable the
uncommit
extension, add this to your~/.hgrc
:[extensions] uncommit =
Actually run the unamend:
hg unamend
- Find the latest saved backup in
.hg/strip-backup
directory hg unbundle .hg/strip-backup/<latest backup>
- 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)".
- if you have
histedit
extension, you can dohg histedit
on it in order to change it (e.g. selectedit
in order to achieve a state just before the commit, i.e. when you can see all changes usinghg diff
).
Don't forget to strip the old head.
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:
- Find the latest saved backup in the .hg/strip-backup/ directory
- Run
hg unbundle .hg/strip-backup/<latest backup>
where<latest backup>
signifies the full filename. - 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. - 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
$
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).
hg merge
and then hg commit -m 'message_for_the_last_commit'
, but it messes the history a bit. –
Monostome 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.