12

Is there a way to edit a commit message in Mercurial on a commit after other commits have occured using TortoiseHg? I've read these posts:

How to edit incorrect commit message in Mercurial?

Mercurial: how to amend the last commit?

and have been able to update a "regular" commit message when it is the latest commit on a branch (using TortoiseHg). However, I haven't been able to figure out how to edit a commit message when other commits have occurred after the one I want to edit. It always edits the last commit.

Based on Ed Cottrell's comment, I did a test where I made two commits without pushing to the central repo, and I still have the same issue - only the last commit message can be edited.

EDIT: I should clarify that I am looking to update a changeset that has been pushed.

Community
  • 1
  • 1
sdoca
  • 7,832
  • 23
  • 70
  • 127
  • Have you pushed to a remote repository since the commit in question? – elixenide Feb 20 '14 at 16:51
  • Yes, so I changed the phase to draft before importing to MQ – sdoca Feb 20 '14 at 16:58
  • That's a different issue; are you trying to change commit messages on patches or on the core repository? – elixenide Feb 20 '14 at 17:02
  • What my final goal is to update a message on commit where I merged a branch back into trunk (default) branch. Not sure if you consider that a patch or not. However, in my testing, first I'm just trying to get to the point where I can edit a commit message when it is not the last commit on the trunk branch (default). – sdoca Feb 20 '14 at 17:21
  • I'm asking about patches because you mentioned MQ, which is a patch management system. If you did a simple merge, that's easier to work with, but still a huge pain. You can use the `hg rebase` extension to move all commits after the one you want to change, then use `--amend` to change the message, then `hg rebase` to reattach the other commits. This is really dicey, though, and a bad idea if this not a purely personal repository. You are probably best off just doing a new commit with a corrected message. – elixenide Feb 20 '14 at 17:26
  • I got the MQ stuff from one of the questions linked to above. Although I have the latest version of Mercurial on my workstation, our central repo is still a 1.9 version. So, I didn't think using ``amend`` would work. We are planning on upgrading the central, but that's out of my hands. Also, I couldn't figure out how to use ``amend`` in TortoiseHg. Do you know if it's possible? – sdoca Feb 20 '14 at 18:33
  • It doesn't sound like MQ is relevant to your question. The hg version in use on the central repo shouldn't matter. You theoretically can do the swapping around with `rebase` that I describe above, but I would strongly recommend just doing another commit with corrected comments. If you do decide to play around with it, there is an "Amend current revision" option on the Commit button dropdown, but, again, it only works on the last revision. – elixenide Feb 20 '14 at 19:10
  • Longish story... we use JIRA and Crucible/FishEye for issue tracking and code reviews. If the JIRA issue is included in the commit message, JIRA (via FishEye) knows that the changeset is related to that issue. We have a workflow set up that enforces that all changesets related to the issue are code reviewed before they can be closed. The merge commit has the JIRA issue in it, but there are no files in the changeset, so I can't add it to a Crucible review and subsequently I can't close my issue. My hope is that changing the message would disassociate it from the issue and allow me to close it. – sdoca Feb 20 '14 at 22:05

3 Answers3

12

Histedit extension (bundled with TortoiseHG now) has a mess command for changing the commit message of historical changesets.

Unfortunately, this command is not supported by the TortoiseHG GUI so you need to run the command from command line.

Andre Holzner
  • 18,333
  • 6
  • 54
  • 63
Lazy Badger
  • 94,711
  • 9
  • 78
  • 110
  • I've enabled histedit in my TortoiseHg. How do you access it from the UI? – sdoca Feb 20 '14 at 22:30
  • Hi, I found this page: http://i-proving.com/2011/01/20/TortoiseHG-How-to-rename-a-changeset/ which shows how to use histedit in conjunction with TortoiseHg. It just creates branches with the old commit. I'm thinking that once you've pushed, changing the comment just isn't feasible. – sdoca Feb 20 '14 at 23:12
4

As long as the change in question is local and hasn't been pushed anywhere, it is possible.

The commit message is used to compute the globally unique hash id that is used for all repositories to determine whether or not they already have a changeset. If you change the commit message, you change the unique hash id and every repo will see it as a "new" changeset. All other repositories that had the old changeset will try to get the new one and ask that you merge it with itself.... This is not a good thing, so the short answer to your question is "don't do it".

If you could definitively purge that change from all other repos, so that only the local copy is left you could essentially get to the "draft" state. Note that if any repo has the "old" changeset, it will be pushed to the central repo someday and cause the mess that we are trying to avoid.


If the changeset is still local (e.g. in draft status), you can use hg commit --amend if it is the parent of the working directory.

If there are changes after it, I would use mq and hg qimport all the changes down to and including the one where you want to edit the commit message. hg qpop -a and then hg qpush to get to the patch that represents the changeset you want to edit. Then hg qrefresh -e and make your changes. Then just hg qfin -a and you should be good to go.

Edward
  • 3,292
  • 1
  • 27
  • 38
4

The advice from Edward is good — if you've pushed your changes to another repository, you should consider them set in stone and not update the commit message or any other aspect of them.

However, we're working on changing this in Mercurial. There is an experimental extension that will allow you to do more extensive history editing and push those edits to other repositories. It is called the Evolve Extension and it enables some behavior that is partly in the core of Mercurial and partly outside core.

When using evolve, you can edit the second-to-last commit message like this

$ hg update .^
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg commit --amend -m 'new commit message'
1 new unstable changesets    
$ hg stabilize
more:[5] old tip changeset
atop:[6] new commit message

The extension allows you to do this as long as the changesets are in the draft phase. To keep them in the draft phase after pushing them somewhere, the repository you push to need to be configured as a non-publishing repository. You can read more about this in the Changeset Evolution Documentation.

Metro Smurf
  • 37,266
  • 20
  • 108
  • 140
Martin Geisler
  • 72,968
  • 25
  • 171
  • 229
  • Thanks. For my specific case, I want to update a comment in a commit that is more than the second-to-last unfortunately. But I've learned a few Mercurial tricks in the meantime. – sdoca Feb 21 '14 at 15:55
  • Found this page while looking for a solution to this specific problem (fixing a commit message in an ancestor changeset). Unfortunately, the Evolve extension still isn't installed by default, and without a `pip` command available, the official installation instructions don't help... I'm looking forward to trying it someday! – Ti Strga Sep 18 '19 at 20:28