在合并之前修改 Git 提交的消息
Posted
技术标签:
【中文标题】在合并之前修改 Git 提交的消息【英文标题】:Amending the message of Git commit made before a merge 【发布时间】:2013-05-08 12:11:12 【问题描述】:我在合并到远程分支之前提交了一些测试代码。这次合并有很多冲突,并且花了一些时间来纠正。所以我的历史看起来是这样的:
7ab562c Merge from remote branch
... whole load of commits brought across from the remote branch...
f3e71c2 Temporary TESTING COMMIT
测试代码很好,我真的只是想更改提交消息。通常我会直接使用git rebase -i f3e71c2^
(因为尚未推送任何内容),但一位同事告诉我这会破坏合并。我真的不想搞砸合并:)
我的同事说得对吗?如果是这样,我有什么可以做的,还是我只需要忍受这段历史?
【问题讨论】:
git commit --amend
?
@kan: 这只适用于修改最新的提交,这里不是这种情况。
推荐少一些恐惧!如果您搞砸了,只需git reset --hard 7ab562c
即可返回您的合并后状态并重试。另外,查看git rerere
让 git 记住如何解决合并冲突。
在我们的商店中,一些不太懂 git 的用户经常会得到一些非常……有创意的历史。通常他们并不关心他们的历史是什么样子,他们只是希望能够轻松地进行同行评审,所以我让他们做类似的事情:git pull
(&解决冲突),git reset --soft origin/develop
(留下事情的状态就像他们在合并之后一样),然后是git commit
。这实际上是在压缩/重新调整他们的更改。
【参考方案1】:
你可以试试git rebase --preserve-merges --interactive
,用:
-p
--preserve-merges
不要忽略合并,而是尝试重新创建它们。
手册页的BUG部分包括:
--preserve-merges --interactive
呈现的待办事项列表不代表修订图的拓扑结构。 编辑提交和重新编写提交消息应该可以正常工作,但尝试重新排序提交往往会产生违反直觉的结果。
正如jthill 的comment 所述(因为如果冲突解决是记录器,-p
将更好地保留合并):
您可以追溯重新合并:
git config rerere.enabled true
git checkout $merge^1
git merge $merge^2
# for Windows:
# git merge $merge^^2
git read-tree --reset -u $merge
git commit -m-
git checkout @-1
正如Soufiane Roui 在the comments 中所指出的:
对于 Windows CMD 用户,使用双插入符号来指向合并提交的父级(例如
$merge^^1
而不是$merge^1
)。 因为插入符号被视为转义字符。
【讨论】:
感谢@VonC,但遗憾的是,这对我不起作用。我reword
ed 测试提交,pick
ed 合并,并且 rebase 仍然在合并时阻塞,抛出 11 个冲突文件。我已经使用 @chrisk 的 git reset
建议回到我原来的位置,我想我会把它留在那里:在这种情况下投入的时间不值得修复。
@ChrisWard 这意味着您需要激活rerere
(git-scm.com/docs/git-rerere) 以记录合并分辨率,这将然后允许在没有--preserve-merge
冲突。
经过进一步研究,rerere
并没有进行这种“数据收集”。由于我刚刚开启,我之前的冲突解决方法没有记录,所以不能使用。我将放弃这项工作,并建议我的同事启用rerere
,以防他们将来陷入这种混乱。
@ChrisWard true,rerere
仅在您之前解决合并冲突并激活 rerere
时才有效。
但是,您可以追溯地重新合并:git config rerere.enabled true; git checkout $merge^1; git merge $merge^2; git read-tree --reset -u $merge; git commit -m-; git checkout @-1
。【参考方案2】:
如果并且仅如果您的同事没有将更改推送/拉到其他地方的 f3e71c2 之上,这将起作用。否则我不知道会发生什么。更改提交消息完全是装饰性的(== 元数据更改),因为您还没有 push
ed 您想要修改的提交,但是如果您的同事推/拉了任何部分,这仍然可能导致历史混乱上面的历史。
(感谢 Abizern 指出这种故障模式)
【讨论】:
消息是提交对象的一部分,它是不可变的。如果你改变了消息,你就改变了提交,这改变了历史。 @Abizern:是的。但是,这仅在提交已被推送到其他地方(他们没有)时才相关。我已经在本地验证了这种策略在这种情况下有效。 @Abizern:但是我想我没有考虑到其他人可能已经同时将顶部提交推送到其他地方。这可能会导致失败/历史混乱,所以我进行了相应的编辑。 这没有回答问题。以上是关于在合并之前修改 Git 提交的消息的主要内容,如果未能解决你的问题,请参考以下文章