如何在 git 中编辑不正确的提交消息(我已推送)?
Posted
技术标签:
【中文标题】如何在 git 中编辑不正确的提交消息(我已推送)?【英文标题】:How do I edit an incorrect commit message in git ( that I've pushed )? 【发布时间】:2010-10-02 05:24:01 【问题描述】:我想修改历史更深的提交消息,并且我已经推送了许多新的提交。
如何更改提交消息?有可能吗?
【问题讨论】:
【参考方案1】:来自 Linus Torvalds 的消息可能会回答您的问题:
Modify/edit old commit messages
简短回答:你不能(如果被推)。
提取(Linus 将 BitKeeper 称为 BK):
旁注,只是出于历史兴趣:在 BK 你可以。
如果你习惯了(就像我一样),它真的很实用。一世 会使用安德鲁的补丁炸弹,注意到有问题,然后 在推出之前对其进行编辑。
我可以用 git 做同样的事情。这本来很容易 只使提交消息不是名称的一部分,并且仍然保证 历史未被触及,并允许“稍后修复 cmets” 东西。
但我没有。
其中一部分纯粹是“内部一致性”。 Git 只是一个 cleaner 系统感谢所有东西都受到 SHA1 保护,并且所有对象都是 无论对象类型如何,都一样对待。是的,有四个 不同种类的物体,它们都非常不同,它们 不能以同样的方式使用,但同时,即使他们 磁盘上的编码可能不同,概念上它们都可以正常工作 一样的。
但内部一致性并不是不灵活的真正借口,而且 显然,如果我们可以在之后修复错误,那将是非常灵活的 他们发生了。所以这不是一个非常有力的论点。
git 不允许你更改提交消息的真正原因结束 起来非常简单:这样,您就可以信任这些消息。如果你允许 人们事后更改它们,消息本质上不是很 值得信赖。
为了完整起见,您可以重写您的本地提交历史记录以反映您想要的内容,如 suggested by sykora(带有一些变基和重置 --hard,喘气!)
但是,一旦您再次发布修改后的历史记录(带有git push origin +master:master
,+
符号会强制推送发生,即使它不会导致“快进"提交)...你might get into some trouble.
从另一个 SO 问题中摘录:
实际上我曾经用 --force 推送到 git.git 存储库并被 Linus BIG TIME 责骂。它会给其他人带来很多问题。一个简单的答案是“不要这样做”。
【讨论】:
好答案。您知道您现在是否能够在较新版本的 git 中更改已推送的提交消息?自 09 年发布以来,有什么变化吗? @DavidWest 同样的原则:你可以重写你的历史并强制推送。 为了使事情更具体,如果您修改/重新设置提交,它们的提交标识符(git index 中的十六进制哈希)不可避免地会发生变化;这意味着编辑后的提交与 git VCS 历史记录中的旧提交不同。也就是说,如果您的开发团队成员不幸已经拉取了旧的提交,他们有义务拉取已编辑的新提交,并在他们的本地工作副本中执行新旧提交之间的合并。 为了方便您的同事,最好重新推送已编辑的提交,从而有利于消除合并同事工作副本的需要。【参考方案2】:目前git replace 可以解决问题。
详细说明: 创建临时工作分支
git checkout -b temp
重置为要替换的提交
git reset --hard <sha1>
用正确的信息修改提交
git commit --amend -m "<right message>"
用新的提交替换旧的提交
git replace <old commit sha1> <new commit sha1>
回到你所在的分支
git checkout <branch>
删除临时分支
git branch -D temp
推
guess
完成。
【讨论】:
@Jonah :当我尝试推送到远程分支时,我收到一条“一切都是最新的”消息 正如另一个答案中提到的:使用 rebase -i 和 reword。它会改写历史。 感谢您提供我一直在寻找的解决方案。你节省了我的时间! @Jonah - 我有一个问题......您的解决方案在本地更新了我的提交日志,但不是远程更新。如何将它们推到那里? @TomaszKuter,我和你有同样的问题。我的提交消息没有远程更新。我通过使用来自 GitHub 的以下帮助解决了这个问题:help.github.com/articles/changing-a-commit-message。遵循:修改旧的或多个提交消息部分的消息。这基本上是 user987419 下面给出的答案 如果您已经更改了提交消息,您可以选择并保存而无需再次更改。【参考方案3】:您可以使用git rebase -i
(针对您分支的分支)
'i' 用于交互。
将您希望更改的提交注释旁边的pick
替换为r
(或reword
),保存并退出,然后您就可以进行编辑了。
git push
再次完成!
【讨论】:
这不允许编辑合并提交的消息。这个命令的一些变体可以做到吗? 尝试rebase
的-p
参数,p
reserves 合并。
我喜欢这个过程,但起初并不太明白答案。如果有人需要帮助,Githulb 帮助页面提供了很好的信息:help.github.com/articles/changing-a-commit-message【参考方案4】:
假设你有一棵这样的树:
dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
首先,checkout
一个临时分支:
git checkout -b temp
在temp
分支上,reset --hard
指向您要更改其消息的提交(例如,该提交是946992
):
git reset --hard 946992
使用amend
更改消息:
git commit --amend -m "<new_message>"
之后,树将如下所示:
dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
\
b886a0 [temp]
然后,cherry-pick
所有在946992
之前的提交从master
到temp
并提交它们,如果你也想更改它们的消息,请使用amend
:
git cherry-pick 9143a9
git commit --amend -m "<new_message>
...
git cherry-pick 5a6057
git commit --amend -m "<new_message>
树现在看起来像这样:
dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
\
b886a0 - 41ab2c - 6c2a3s - 7c88c9 [temp]
现在强制将临时分支推送到远程:
git push --force origin temp:master
最后一步,在本地删除分支master
,git fetch origin
从服务器拉取分支master
,然后切换到分支master
并删除分支temp
。
现在您的本地和远程都将更新所有消息。
【讨论】:
【参考方案5】:在我们的商店中,我介绍了将可识别命名的带注释标签添加到带有错误消息的提交的约定,并使用注释作为替换。
尽管这对运行随意的“git log”命令的人没有帮助,但它确实为我们提供了一种方法来修复 cmets 中不正确的错误跟踪器引用,并且我所有的构建和发布工具都理解该约定。
这显然不是一个通用的答案,但它可能是人们可以在特定社区内采用的东西。我敢肯定,如果这在更大范围内使用,最终可能会出现某种瓷器支撑...
【讨论】:
"git notes" 可能有类似的目的【参考方案6】:(来自http://git.or.cz/gitwiki/GitTips#head-9f87cd21bcdf081a61c29985604ff4be35a5e6c0)
如何更改历史更深的提交
由于 Git 中的历史记录是不可变的,因此修复除最近提交(不是分支头的提交)之外的任何内容都需要从更改的提交中重写历史记录并转发。
您可以为此使用 StGIT,必要时初始化分支,取消提交到您要更改的提交,必要时弹出它,进行更改然后刷新补丁(如果要更正提交消息,请使用 -e 选项) ,然后推送所有内容并 stg 提交。
或者你可以使用 rebase 来做到这一点。创建新的临时分支,使用 git reset --hard 将其倒回到您要更改的提交,更改该提交(它将是当前头部的顶部),然后使用 git rebase --onto 在更改的提交之上重新设置分支。
或者您可以使用 git rebase --interactive,它允许进行各种修改,例如补丁重新排序、折叠、...
我认为这应该可以回答您的问题。但是,请注意,如果您将代码 推送 到远程存储库并且人们已经从中提取,那么这将会弄乱他们的代码历史以及他们所做的工作。所以要小心。
【讨论】:
理论上的好答案,在实践中非常危险:见***.com/questions/253055#432518【参考方案7】:如果您使用的是 Git 扩展: 进入 Commit 屏幕,底部应该有一个“Amend Commit”复选框,如下所示:
【讨论】:
@KrunalPandya 是的,或者直接按 commit & push以上是关于如何在 git 中编辑不正确的提交消息(我已推送)?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Mercurial 中编辑不正确的提交消息? [复制]
如何在GIT Rebase Interactive Squash之后删除远程存储库上的历史记录提交消息