336

我目前正在使用 TortoiseHg (Mercurial) 并且不小心提交了不正确的提交消息。如何在存储库中编辑此提交消息?

4

12 回答 12

252

更新: Mercurial 已添加--amend,现在应该是首选选项


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

重要提示:这将永久删除最新的提交(或拉取)。因此,如果您完成了hg update该提交,则该提交不再在您的工作目录中,那么它就永远消失了。所以先复制一份。

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

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

于 2009-03-08T05:05:34.900 回答
91

好吧,我曾经这样做过:

想象一下,您有 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
于 2009-07-27T13:10:21.783 回答
70

好消息:hg 2.2刚刚添加了类似 git 的--amend选项。

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

一种

于 2012-05-13T13:12:36.103 回答
49

我知道这是一篇旧帖子,您将问题标记为已回答。我最近也在寻找同样的东西,我发现这个histedit扩展非常有用。该过程在这里解释:

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

于 2011-01-01T15:30:32.250 回答
20

最后一次操作是有问题的提交

要在最后一次 mercurial 操作是提交时更改最后一次提交的提交消息,您可以使用

$ hg rollback

回滚最后一次提交并使用新消息重新提交:

$ hg ci -m 'new message'

但要小心,因为回滚命令也会回滚以下操作:

  • 进口
    • 推送(以此存储库为目标)
    • 解绑

(见hg help rollback

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

更改任何其他提交消息

您可以使用与 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

将其复制到一个空目录并执行它,例如通过:

$ 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 测试)

于 2011-08-31T20:13:18.087 回答
20

在 TortoiseHg 中,右键单击要修改的版本。选择修改历史记录->导入 MQ。这会将所有修订版转换为 Mercurial 变更集中的选定修订版(包括所选修订版)到 Mercurial Queue 补丁中。选择要修改消息的补丁,它应该会自动将屏幕更改为 MQ 编辑器。编辑屏幕中间的消息,然后单击 QRefresh。最后,右键单击补丁并选择 Modify History->Finish Patch,这会将其从补丁转换回更改集。

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

于 2012-08-16T19:38:34.123 回答
12

编辑:正如用户所指出的,不要使用 MQ,使用commit --amend. 这个答案现在主要具有历史意义。

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

  1. 通过在 hgrc 中添加类似这样的内容来启用 MQ 扩展:

    [extensions]
    mq =
    
  2. 更新您要编辑的变更集,通常提示:

    hg up $rev
    
  3. 将当前变更集导入队列:

    hg qimport -r .
    
  4. 刷新补丁,并编辑提交信息:

    hg qrefresh -e
    
  5. 完成所有应用的补丁(在本例中为一个)并将它们存储为常规变更集:

    hg qfinish -a
    

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

于 2010-08-19T15:29:13.233 回答
6

Rollback-and-reapply 是一个非常简单的解决方案,但它只能帮助最后一次提交。Mercurial Queues 功能更强大(请注意,您需要启用 Mercurial Queues Extension才能使用“hg q*”命令)。

于 2009-10-26T08:06:50.967 回答
1

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

于 2010-08-11T23:18:08.597 回答
1

如果我要编辑的版本不是那么旧,我会使用一种技巧:

假设您的版本为 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
于 2013-08-19T13:46:40.573 回答
0

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

// set current tip to rev 497
hg debugsetparents 497
hg debugrebuildstate
// hg add/remove if needed
hg commit
hg strip [-n] 498
于 2011-11-30T23:10:09.397 回答
0

上面讨论中的一个小宝石——感谢@Codest 和@Kevin Pullin。在 TortoiseHg 中,提交按钮旁边有一个下拉选项。选择“修改当前版本”会返回注释和文件列表。太有用了。

于 2014-12-13T19:40:11.323 回答