【发布时间】:2010-10-12 00:06:13
【问题描述】:
我目前正在使用 TortoiseHg (Mercurial) 并且不小心提交了不正确的提交消息。如何在存储库中编辑此提交消息?
【问题讨论】:
-
有
hg metaedit
标签: version-control mercurial tortoisehg commit-message mercurial-commit
我目前正在使用 TortoiseHg (Mercurial) 并且不小心提交了不正确的提交消息。如何在存储库中编辑此提交消息?
【问题讨论】:
hg metaedit
标签: version-control mercurial tortoisehg commit-message mercurial-commit
更新: Mercurial 添加了--amend,应该是the preferred option now。
您可以使用hg rollback 回滚最后一次提交(但只有最后一次),然后重新应用它。
重要:这永久删除最新的提交(或拉)。因此,如果您已经完成了hg update,那么该提交不再在您的工作目录中,那么它就永远消失了。 所以先复制一份。
除此之外,您无法更改存储库的历史记录(包括提交消息),因为其中的所有内容都经过校验和。您唯一能做的就是在给定变更集之后修剪历史记录,然后相应地重新创建它。
如果您已经发布了您的更改(除非您可以获得所有副本),并且您也不能“重写历史”包括 GPG 签名的提交(由其他人),那么这些都不会起作用。
【讨论】:
rollback 时,请始终包含一个警告,表明它会永久删除最新的提交(或拉取)。因此,如果您已经完成了hg update(就像他所做的那样)并且该提交不再在您的工作目录中,那么它就永远消失了。
嗯,我以前是这样的:
想象一下,您有 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 编辑提交消息以到达正确的补丁。
hg qfinish -a 而不是 hg qdelete -r ...,因为 qdelete 的帮助说“不得应用补丁”,在示例中补丁已应用(并且 hgbook 声明“qbase 和 qtip 标识“最底层”和最顶层应用的补丁”)。
回滚并重新应用是非常简单的解决方案,但它只能对最后一次提交有所帮助。 Mercurial Queues 功能更强大(请注意,您需要 enable Mercurial Queues Extension 才能使用“hg q*”命令)。
【讨论】:
我是这样做的。首先,不要推动您的更改,否则您将不走运。获取并安装collapse 扩展。提交另一个虚拟变更集。然后使用 collapse 将前两个变更集合并为一个。它将提示您输入新的提交消息,并为您提供已经拥有的消息作为起点。你已经有效地改变了你原来的提交信息。
【讨论】:
编辑:正如用户所指出的,不要使用 MQ,使用commit --amend。这个答案现在主要是具有历史意义的。
正如其他人所提到的,MQ 扩展更适合这项任务,而且您不会冒破坏工作的风险。为此:
通过向 hgrc 添加类似的内容来启用 MQ 扩展:
[extensions]
mq =
更新您要编辑的变更集,通常提示:
hg up $rev
将当前变更集导入队列:
hg qimport -r .
刷新补丁,编辑提交信息:
hg qrefresh -e
完成所有应用的补丁(在本例中为一个)并将它们存储为常规变更集:
hg qfinish -a
我不熟悉 TortoiseHg,但是命令应该和上面的类似。我还认为值得一提的是,编辑历史是有风险的。只有在您绝对确定没有将变更集推送到或从其他任何地方拉出时,才应该这样做。
【讨论】:
qimport 打印“中止:修订版 hg up,导入从包括 hg qrefresh -e 并推送所有内容 - 就像安东尼奥的回答中所述。hg uphg qimport -r rev::.hg qpop --allhg qpushhg qrefresh -e(在编辑器中编辑提交消息)hg qpush --allhg qfinish --all
我知道这是一篇旧帖子,您将问题标记为已回答。我最近也在寻找同样的东西,我发现histedit 扩展非常有用。这里解释了这个过程:
http://knowledgestockpile.blogspot.com/2010/12/changing-commit-message-of-revision-in.html
【讨论】:
abort: can't rebase immutable changeset 43ab8134e7af,你必须首先将提交翻转到草稿:hg phase -f -d 45:c3a3a271d11c - 请参阅Mecurial Phases了解更多信息。
要在最后一次 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 测试)
【讨论】:
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
【讨论】:
好消息:hg 2.2 just added git like --amend 选项。
在tortoiseHg中,您可以通过选择提交按钮右侧的黑色箭头来使用“修改当前版本”
【讨论】:
nothing changed
在 TortoiseHg 中,右键单击要修改的版本。选择修改历史记录->导入 MQ。这会将所有修订版转换为 Mercurial 变更集中的选定修订版(包括所选修订版)到 Mercurial Queue 补丁中。选择要修改消息的补丁,它应该会自动将屏幕更改为 MQ 编辑器。编辑屏幕中间的消息,然后单击 QRefresh。最后,右键单击补丁并选择修改历史记录->完成补丁,这会将补丁从补丁转换回更改集。
哦,这假设 MQ 是此存储库上 TortoiseHG 的一个活动扩展。如果没有,您应该能够单击 File->Settings,单击 Extensions,然后单击 mq 复选框。它应该警告您必须在扩展程序处于活动状态之前关闭 TortoiseHg,因此请关闭并重新打开。
【讨论】:
如果我要编辑的版本不是那么旧,我会使用一个技巧:
假设您的版本为 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 中,提交按钮旁边有一个下拉选项。选择“修改当前版本”会返回注释和文件列表。太有用了。
【讨论】: