如何在 Mercurial 中编辑不正确的提交消息? [复制]

Posted

技术标签:

【中文标题】如何在 Mercurial 中编辑不正确的提交消息? [复制]【英文标题】:How to edit incorrect commit message in Mercurial? [duplicate] 【发布时间】:2010-10-12 00:06:13 【问题描述】:

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

【问题讨论】:

hg metaedit 【参考方案1】:

更新: Mercurial 添加了--amend,应该是the preferred option now。


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

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

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

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

【讨论】:

我刚刚看到一个人因为他遵循了这个建议而得到了一个承诺。当建议某人使用rollback 时,请始终包含一个警告,表明它会永久删除最新的提交(或拉取)。因此,如果您已经完成了hg update(就像他所做的那样)并且该提交不再在您的工作目录中,那么它就永远消失了。 避免回滚/翻转灾难的最简单方法是执行简单的更改(添加或删除间距)并在下一个提交消息中解释您的错误。 @rxgx 您应该将此作为单独的答案发布,因为它可能是这里的最佳答案。 老实说,我很惊讶它花了整整两年的时间才添加警告。如果在添加警告之前我需要知道如何执行此操作,我会遵循此答案中的建议并因此失去工作。【参考方案2】:

嗯,我以前是这样的:

想象一下,您有 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

【讨论】:

您也可以在使用hg qpop 后使用hg qrefresh -e 编辑提交消息以到达正确的补丁。 当然,您可以使用任何其他编辑器来代替“joe”。 +1 这是我无法使用简单回滚时使用的方法。 Windows 用户应该注意记事本对 diff 文件中的 eol 不满意。 "r.3" 是第三次提交,从历史开始计算,通常不是最近一次提交。我将其更改为 3 位数,以防止其他人犯与我相同的错误。 (顺便说一句,要撤消“qimport”,您可以使用“hg qfinish -a”)。 我是 MQ 的新手,但我认为您必须使用 hg qfinish -a 而不是 hg qdelete -r ...,因为 qdelete 的帮助说“不得应用补丁”,在示例中补丁已应用(并且 hgbook 声明“qbase 和 qtip 标识“最底层”和最顶层应用的补丁”)。【参考方案3】:

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

【讨论】:

【参考方案4】:

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

【讨论】:

【参考方案5】:

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

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

    通过向 hgrc 添加类似的内容来启用 MQ 扩展:

    [extensions]
    mq =
    

    更新您要编辑的变更集,通常提示:

    hg up $rev
    

    将当前变更集导入队列:

    hg qimport -r .
    

    刷新补丁,编辑提交信息:

    hg qrefresh -e
    

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

    hg qfinish -a
    

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

【讨论】:

用 Mercurial 1.7.5 对其进行了测试,但您的程序不起作用。 qimport 打印“中止:修订版 有未管理的子代”。有效的方法不是调用hg up,导入从包括 到提示的所有内容,弹出所有内容,然后调用hg qrefresh -e 并推送所有内容 - 就像安东尼奥的回答中所述。 你所说的“流行一切”是什么意思? 他的意思是(将修订版重命名为“rev”)类似于答案,但将所有后代从 mq 堆栈中弹出。类似于:hg uphg qimport -r rev::.hg qpop --allhg qpushhg qrefresh -e(在编辑器中编辑提交消息)hg qpush --allhg qfinish --all【参考方案6】:

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

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

【讨论】:

非常不错的扩展,感谢您的建议! 我最终进入了这个页面,因为 histedit 不适用于合并提交。只是一个警告,你不能用这个重命名一个合并。 当前版本的扩展甚至支持专门用于编辑提交消息的“消息”命令。 赞成。一旦您学会使用 histedit,Histedit 就是最简单的方法。 如果你得到abort: can't rebase immutable changeset 43ab8134e7af,你必须首先将提交翻转到草稿:hg phase -f -d 45:c3a3a271d11c - 请参阅Mecurial Phases了解更多信息。【参考方案7】:

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

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

$ hg rollback

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

$ hg ci -m 'new message'

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

导入 拉 推送(以此存储库为目标) 解绑

(见hg help rollback

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

更改任何其他提交消息

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

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

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

要使用 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 测试)

【讨论】:

【参考方案8】:

MQ 扩展和debug commands 还有另一种方法。这是在不丢失数据的情况下修改历史的一般方法。让我假设与Antonio相同的情况。

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

【讨论】:

【参考方案9】:

好消息:hg 2.2 just added git like --amend 选项。

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

【讨论】:

如果您没有更改文件的内容,则不会让您提交... nothing changed【参考方案10】:

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

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

【讨论】:

这是我一直做的——这是最简单的方法! 赞成。这太棒了,因为它允许您为多个草稿变更集执行此操作 - 例如,如果您在所有提交中输入了错误的票号! :D【参考方案11】:

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

假设您的版本为 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

【讨论】:

【参考方案12】:

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

【讨论】:

这更适合作为评论。

以上是关于如何在 Mercurial 中编辑不正确的提交消息? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 git 中编辑不正确的提交消息(我已推送)?

如何在Mercurial中验证和实施提交消息?

提交后修复Mercurial存储库中的重命名

你如何在 Mercurial 上“回滚”最后一次提交?

使用提交消息 mercurial 查找变更集

在使用 Mercurial 移植大量变更集时更改提交消息