我目前正在使用TortoiseHg (Mercurial),不小心提交了一个错误的提交消息。如何在存储库中编辑这条提交消息?


更新:Mercurial增加了-修正,现在应该是首选的选项。


您可以使用hg回滚回滚上一次提交(但只能是最后一次),然后重新应用它。

重要的是:这将永久地删除最新的提交(或拉取)。所以如果你做了hg更新,commit不再在你的工作目录中,那么它就永远消失了。所以先复制一份。

除此之外,您不能更改存储库的历史记录(包括提交消息),因为其中的所有内容都是校验和的。您唯一能做的就是在给定的变更集之后修剪历史记录,然后相应地重新创建它。

如果您已经发布了您的更改(除非您可以获得所有的副本),这些都将不起作用,并且您也不能“重写历史”,包括gpg签名提交(由其他人)。


我以前是这么做的:

想象一下,您有500个提交,错误的提交消息在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

回滚-重新应用是一个非常简单的解决方案,但它只对最后一次提交有帮助。Mercurial Queues功能强大得多(注意,为了使用“hg q*”命令,您需要启用Mercurial Queues Extension)。


我是这样做的。首先,不要强迫你的改变,否则你就不走运了。抓取并安装崩溃扩展。提交另一个虚拟变更集。然后使用折叠将前两个更改集合并为一个。它将提示您输入一条新的提交消息,为您提供您已经拥有的作为起点的消息。您已经有效地更改了原来的提交消息。


编辑:正如用户指出的那样,不要使用MQ,而是使用提交—修改。这个答案现在大多具有历史意义。

正如其他人所提到的,MQ扩展更适合此任务,并且您不会冒破坏工作的风险。这样做:

启用MQ扩展,在hgrc中添加如下内容: (扩展) mq = 更新到您想要编辑的变更集,通常提示: Hg上升$rev 将当前的变更集导入队列: Hg qimport -r。 刷新补丁,编辑提交消息: Hg qrefresh -e 完成所有应用的补丁(在本例中是一个),并将它们存储为常规更改集: Hg qfinish a

我不熟悉TortoiseHg,但是命令应该与上面的类似。我还认为值得一提的是,编辑历史是有风险的;只有在您绝对确定更改集没有被推送到其他地方或从其他地方拉出时,才应该这样做。


我知道这是一个老帖子,你把问题标记为答案。我正在寻找同样的事情最近,我发现histedit扩展非常有用。这个过程解释如下:

http://knowledgestockpile.blogspot.com/2010/12/changing-commit-message-of-revision-in.html


最后一个操作就是问题中的提交

当上次mercurial操作是可以使用的提交时,更改上次提交的提交消息

$ hg rollback

回滚上次提交并使用新消息重新提交:

$ hg ci -m 'new message'

rollback命令还会进行以下回滚操作,请谨慎使用:

进口 拉 推送(以这个存储库作为目标) 分类定价

(参见hg help rollback)

因此,如果您不确定最后一个mercurial命令是否是hg ci,请不要使用hg回滚。

更改任何其他提交消息

您可以使用随Mercurial分发的mq扩展来更改任何提交的提交消息。

这种方法只在公共存储库中还没有包含您想要重命名的更改集的克隆存储库时有用,因为这样做会改变它和所有后续更改集的更改集哈希值。

这意味着您必须能够删除包含您想要重命名的更改集的所有现有克隆,否则在它们之间推/拉将不起作用。

要使用mq扩展,您必须显式地启用它,例如在UNIX下检查~/。Hgrc,应包含以下行:

[extensions]
mq=

假设您想更改修订X -首先qimport导入修订X和后续版本。现在它们被注册为应用补丁的堆栈。弹出(qpop)除X之外的整个堆栈,使X可以通过qrefresh进行更改。提交消息更改后,您必须再次推送所有补丁(qpop)以重新应用它们,即重新创建以下修订。补丁的堆栈是不需要的,因此它可以通过qfinish删除。

下面的演示脚本显示了所有操作。在本例中,第三个变更集的提交消息被重命名。

# 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

复制到一个空目录,然后执行,例如via:

$ bash test.sh 2>&1 | tee log

输出应该包括原始的变更集消息:

+ hg log
[..]
2   53bc13f21b04   2011-08-31 17:26 +0200   juser
  changeset message 3

重命名操作更改的消息:

+ hg log
[..]
2   3ff8a832d057   2011-08-31 17:26 +0200   juser
  CHANGED MESSAGE

(用Mercurial 4.5.2测试)


使用MQ扩展和调试命令还有另一种方法。这是在不丢失数据的情况下修改历史记录的一种通用方法。让我假设和安东尼奥的情况一样。

// set current tip to rev 497
hg debugsetparents 497
hg debugrebuildstate
// hg add/remove if needed
hg commit
hg strip [-n] 498

好消息:hg 2.2刚刚增加了git的修改选项。

在tortoiseHg中,你可以通过选择提交按钮右侧的黑色箭头来使用“修改当前修订”


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.

哦,这里假设MQ是这个存储库上TortoiseHG的活动扩展。如果没有,您应该能够单击File->Settings,单击Extensions,然后单击mq复选框。它应该警告你,你必须关闭TortoiseHg之前的扩展是活跃的,所以关闭并重新开放。


如果我想编辑的版本不是那么旧,我会使用一个hack:

假设你的转速是500,而你想编辑497。

hg export -o rev497 497
hg export -o rev498 498
hg export -o rev499 499
hg export -o rev500 500

编辑rev497文件并更改消息。(它位于以“#”开头的第一行之后)

hg import rev497
hg import rev498
hg import rev499
hg import rev500

上面讨论的一个小宝石-感谢@Codest和@Kevin Pullin。 在TortoiseHg中,在提交按钮旁边有一个下拉选项。选择“修正当前修订”会带回注释和文件列表。所以有用。