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?
-
There is `hg metaedit` – Thomas Ahle Oct 01 '21 at 00:27
12 Answers
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).
-
107I 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 a `hg update` (like he had) and that commit is no longer in your working directory then it's gone forever. – Ry4an Brase Aug 19 '10 at 15:14
-
40The 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. – rxgx Aug 16 '11 at 00:33
-
3@rxgx you should post this as a separate answer since it is probably the best answer here. – Sled Sep 15 '11 at 14:21
-
I'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. – Clonkex Nov 23 '17 at 23:47
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

- 31,095
- 13
- 107
- 185

- 2,281
- 1
- 15
- 26
-
5You can also edit the commit message with `hg qrefresh -e` after using `hg qpop` to arrive at the right patch. – Martin Geisler Jul 27 '09 at 21:52
-
4Of course instead of 'joe' you can use any other editor of choice. – Kees de Kooter Jan 06 '10 at 20:27
-
1+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. – Mizipzor Jun 09 '10 at 13:44
-
"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'). – Nickolay Mar 06 '11 at 21:24
-
4I am new to MQs but I think that you have to use `hg qfinish -a` instead of `hg 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'). – maxschlepzig Aug 30 '11 at 20:52
-
-
What to do in this scenario..? ``hg qimport -r 301:tip `` ``abort: revision 301 is the root of more than one branch`` – OZZIE Sep 24 '15 at 06:56
-
I 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. – badcompany Aug 16 '16 at 16:13
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

- 8,084
- 8
- 48
- 62

- 3,362
- 2
- 36
- 52
-
5Doesn't let you commit if you haven't changed the contents of the files though ... `nothing changed` – Luciano Oct 07 '16 at 12:41
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

- 31,692
- 43
- 108
- 125
-
-
2I ended up on this page because histedit does not work on merge commits. Just a warning, you can't rename a merge with this. – Benbob Oct 10 '11 at 02:12
-
3Current versions of the extension even support "message" command specifically for editing commit messages. – Sergii Volchkov Dec 05 '11 at 15:12
-
Upvoted. Histedit is the easiest way to do this, once you learn to use histedit. – Ken Mason May 01 '13 at 19:01
-
1If 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](http://www.logilab.org/blogentry/88203) for more. – Daniel Sokolowski Sep 03 '13 at 13:13
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 <juser@example.org>' >> .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)

- 3,394
- 1
- 19
- 32

- 35,645
- 14
- 145
- 182
In TortoiseHg, right-click on the revision you want to modify. Choose Modify History->Import MQ. That will convert all the revisions up to and including the selected revision from Mercurial changesets into Mercurial Queue patches. Select the Patch you want to modify the message for, and it should automatically change the screen to the MQ editor. Edit the message which is in the middle of the screen, then click QRefresh. Finally, right click on the patch and choose Modify History->Finish Patch, which will convert it from a patch back into a change set.
Oh, this assumes that MQ is an active extension for TortoiseHG on this repository. If not, you should be able to click File->Settings, click Extensions, and click the mq checkbox. It should warn you that you have to close TortoiseHg before the extension is active, so close and reopen.

- 353
- 2
- 10
-
-
1Upvoted. 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 – May 06 '14 at 19:47
EDIT: As pointed out by users, don't use MQ, use commit --amend
. This answer is mostly of historic interest now.
As others have mentioned the MQ extension is much more suited for this task, and you don't run the risk of destroying your work. To do this:
Enable the MQ extension, by adding something like this to your hgrc:
[extensions] mq =
Update to the changeset you want to edit, typically tip:
hg up $rev
Import the current changeset into the queue:
hg qimport -r .
Refresh the patch, and edit the commit message:
hg qrefresh -e
Finish all applied patches (one, in this case) and store them as regular changesets:
hg qfinish -a
I'm not familiar with TortoiseHg, but the commands should be similar to those above. I also believe it's worth mentioning that editing history is risky; you should only do it if you're absolutely certain that the changeset hasn't been pushed to or pulled from anywhere else.

- 655
- 4
- 9
-
3Tested it with Mercurial 1.7.5 and your procedure does not work. A `qimport` prints 'abort: revision
has unmanaged children'. What works is not calling `hg up`, importing everything from including – maxschlepzig Aug 30 '11 at 20:41to the tip, pop everything, call then `hg qrefresh -e` and pushing everything - like described in Antonio's answer. -
1
-
He 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` – Joshua Goldberg Oct 11 '16 at 03:01
Rollback-and-reapply is realy simple solution, but it can help only with the last commit. Mercurial Queues is much more powerful thing (note that you need to enable Mercurial Queues Extension in order to use "hg q*" commands).

- 576
- 4
- 10
One hack i use if the revision i want to edit is not so old:
Let's say you're at rev 500 and you want to edit 497.
hg export -o rev497 497
hg export -o rev498 498
hg export -o rev499 499
hg export -o rev500 500
Edit rev497 file and change the message. (It's after first lines preceded by "#")
hg import rev497
hg import rev498
hg import rev499
hg import rev500

- 307
- 4
- 15
I did it this way. Firstly, don't push your changes or you are out of luck. Grab and install the collapse extension. Commit another dummy changeset. Then use collapse to combine the previous two changesets into one. It will prompt you for a new commit message, giving you the messages that you already have as a starting point. You have effectively changed your original commit message.

- 31
- 1
A little gem in the discussion above - thanks to @Codest and @Kevin Pullin. In TortoiseHg, there's a dropdown option adjacent to the commit button. Selecting "Amend current revision" brings back the comment and the list of files. SO useful.

- 1
There is another approach with the MQ extension and the debug commands. This is a general way to modify history without losing data. Let me assume the same situation as Antonio.
// set current tip to rev 497
hg debugsetparents 497
hg debugrebuildstate
// hg add/remove if needed
hg commit
hg strip [-n] 498