How to edit incorrect commit message in Mercurial?
Solution 1
Update: Mercurial has added --amend
which should be the preferred option now.
You can rollback the last commit (but only the last one) with hg rollback
and then reapply it.
Important: this permanently removes the latest commit (or pull). So if you've done a hg update
that commit is no longer in your working directory then it's gone forever. So make a copy first.
Other than that, you cannot change the repository's history (including commit messages), because everything in there is check-summed. The only thing you could do is prune the history after a given changeset, and then recreate it accordingly.
None of this will work if you have already published your changes (unless you can get hold of all copies), and you also cannot "rewrite history" that include GPG-signed commits (by other people).
Solution 2
Well, I used to do this way:
Imagine, you have 500 commits, and your erroneous commit message is in r.498.
hg qimport -r 498:tip
hg qpop -a
joe .hg/patches/498.diff
(change the comment, after the mercurial header)
hg qpush -a
hg qdelete -r qbase:qtip
Solution 3
Good news: hg 2.2 just added git like --amend
option.
and in tortoiseHg, you can use "Amend current revision" by select black arrow on the right of commit button
Solution 4
I know this is an old post and you marked the question as answered. I was looking for the same thing recently and I found the histedit
extension very useful. The process is explained here:
http://knowledgestockpile.blogspot.com/2010/12/changing-commit-message-of-revision-in.html
Solution 5
Last operation was the commit in question
To change the commit message of the last commit when the last mercurial operation was a commit you can use
$ hg rollback
to roll back the last commit and re-commit it with the new message:
$ hg ci -m 'new message'
But be careful because the rollback command also rolls back following operations:
- import
- pull
- push (with this repository as the destination)
- unbundle
(see hg help rollback
)
Thus, if you are not sure if the last mercurial command was a hg ci
, don't use hg rollback
.
Change any other commit message
You can use the mq extension, which is distributed with Mercurial, to change the commit message of any commit.
This approach is only useful when there aren't already cloned repositories in the public that contain the changeset you want to rename because doing so alters the changeset hash of it and all following changesets.
That means that you have to be able to remove all existing clones that include the changeset you want to rename, or else pushing/pulling between them wouldn't work.
To use the mq extension you have to explicitly enable it, e.g. under UNIX check your ~/.hgrc
, which should contain following lines:
[extensions]
mq=
Say that you want to change revision X - first qimport
imports revisions X and following. Now they are registered as a stack of applied patches. Popping (qpop
) the complete stack except X makes X available for changes via qrefresh
. After the commit message is changed you have to push all patches again (qpop
) to re-apply them, i.e. to recreate the following revisions. The stack of patches isn't needed any, thus it can be removed via qfinish
.
Following demo script shows all operations in action. In the example the commit message of third changeset is renamed.
# test.sh
cd $(dirname $0)
set -x -e -u
echo INFO: Delete old stuff
rm -rf .hg `seq 5`
echo INFO: Setup repository with 5 revisions
hg init
echo '[ui]' > .hg/hgrc
echo 'username=Joe User <[email protected]>' >> .hg/hgrc
echo 'style = compact' >> .hg/hgrc
echo '[extensions]' >> .hg/hgrc
echo 'mq=' >> .hg/hgrc
for i in `seq 5`; do
touch $i && hg add $i && hg ci -m "changeset message $i" $i
done
hg log
echo INFO: Need to rename the commit message on the 3rd revision
echo INFO: Displays all patches
hg qseries
echo INFO: Import all revisions including the 3rd to the last one as patches
hg qimport -r $(hg identify -n -r 'children(2)'):tip
hg qseries
echo INFO: Pop patches
hg qpop -a
hg qseries
hg log
hg parent
hg commit --amend -m 'CHANGED MESSAGE'
hg log
echo INFO: Push all remaining patches
hg qpush -a
hg log
hg qseries
echo INFO: Remove all patches
hg qfinish -a
hg qseries && hg log && hg parent
Copy it to an empty directory an execute it e.g. via:
$ bash test.sh 2>&1 | tee log
The output should include the original changeset message:
+ hg log
[..]
2 53bc13f21b04 2011-08-31 17:26 +0200 juser
changeset message 3
And the rename operation the changed message:
+ hg log
[..]
2 3ff8a832d057 2011-08-31 17:26 +0200 juser
CHANGED MESSAGE
(Tested with Mercurial 4.5.2)
maxyfc
01011001 01100101 01110100 00100000 01100001 01101110 01101111 01110100 01101000 01100101 01110010 00100000 01110000 01110010 01101111 01100111 01110010 01100001 01101101 01101101 01100101 01110010 00101110
Updated on July 08, 2022Comments
-
maxyfc almost 2 years
I am currently using TortoiseHg (Mercurial) and accidentally committed an incorrect commit message. How do I go about editing this commit message in the repository?
-
Martin Geisler almost 15 yearsYou can also edit the commit message with
hg qrefresh -e
after usinghg qpop
to arrive at the right patch. -
user2649601 over 14 yearsOf course instead of 'joe' you can use any other editor of choice.
-
Mizipzor about 14 years+1 this is the approach I use when I cant use the simple rollback. Windows users should note that notepad isnt happy about the eol in the diff file.
-
Ry4an Brase almost 14 yearsI just watched a guy get a commit toasted because he followed this advice. When suggesting someone use
rollback
please always include a warning that it permanently removes the latest commit (or pull). So if you've done ahg update
(like he had) and that commit is no longer in your working directory then it's gone forever. -
Solomon Duskis over 13 years"r.3" is the third commit, counted from the beginning of history, typically not one of the recent commits. I changed it to a 3-digit to prevent other people from making the same mistake I did. (By the way, to undo 'qimport' you can use 'hg qfinish -a').
-
unexist about 13 yearsReally nice extension, thanks for the suggestion!
-
rxgx almost 13 yearsThe easiest way to avoid rollback/rollover disasters is to perform a simple change (add or remove spacing) and explain your mistake in the next commit message.
-
maxschlepzig almost 13 yearsTested it with Mercurial 1.7.5 and your procedure does not work. A
qimport
prints 'abort: revision <rev> has unmanaged children'. What works is not callinghg up
, importing everything from including <rev> to the tip, pop everything, call thenhg qrefresh -e
and pushing everything - like described in Antonio's answer. -
maxschlepzig almost 13 yearsI am new to MQs but I think that you have to use
hg qfinish -a
instead ofhg qdelete -r ...
because the help to qdelete says 'The patches must not be applied', where in the example the patches are applied (and the hgbook states that 'qbase and qtip identify the “bottom-most” and topmost applied patches'). -
Sled almost 13 years@rxgx you should post this as a separate answer since it is probably the best answer here.
-
Benbob over 12 yearsI ended up on this page because histedit does not work on merge commits. Just a warning, you can't rename a merge with this.
-
Sergii Volchkov over 12 yearsCurrent versions of the extension even support "message" command specifically for editing commit messages.
-
gw0 almost 12 years
hg qfinish -a
works well and also removes files in.hg/patches/
. -
Milos almost 12 yearsWhat do you mean by 'pop everything'?
-
Rune Andersen almost 12 yearsThis is what I always do - it is the easiest way!
-
Ken Mason about 11 yearsUpvoted. Histedit is the easiest way to do this, once you learn to use histedit.
-
Daniel Sokolowski almost 11 yearsIf you get
abort: can't rebase immutable changeset 43ab8134e7af
you must first flip the commit to draft:hg phase -f -d 45:c3a3a271d11c
- see Mecurial Phases for more. -
jedd.ahyoung about 10 yearsUpvoted. This is awesome because it lets you do this for multiple draft changesets - say, for instance, if you put the wrong ticket number in all of your commits! :D
-
Werner over 9 yearsThis is better-suited as a comment.
-
OZZIE almost 9 yearsWhat to do in this scenario..?
hg qimport -r 301:tip
abort: revision 301 is the root of more than one branch
-
badcompany almost 8 yearsI think qdelete is still needed since I got "abort: source has mq patches applied" message while pushing the commits. After qdelete 'hg push' was successful.
-
Luciano over 7 yearsDoesn't let you commit if you haven't changed the contents of the files though ...
nothing changed
-
Joshua Goldberg over 7 yearsHe means (to rename a revision "rev") something analogous to the answer, but popping all the descendents off the mq stack. Something like:
hg up
hg qimport -r rev::.
hg qpop --all
hg qpush
hg qrefresh -e
(to edit the commit message in an editor)hg qpush --all
hg qfinish --all
-
Clonkex over 6 yearsI'm pretty astounded that it took two whole years to add the warning, honestly. If I had needed to know how to do this before the warning was added I would have followed the advice in this answer and lost work because of it.