我如何在git中编辑不正确的提交信息(我已经推送了)?
我想在历史中更深入地修改提交消息,并推出了许多新的提交。
如何更改提交消息? 可能吗?
来自Linus Torvalds的消息可能会回答你的问题:
修改/编辑旧的提交消息
简短的回答:你不能(如果推)。
提取(Linus将BitKeeper称为BK):
注意,只是出于历史利益:在BK你可以。
如果你习惯了(就像我一样),这真的很实用。 我会申请来自安德鲁的补丁炸弹,注意到有什么地方是错误的,只是编辑它之前推出。
我可以用git做同样的事情。 只要提交的信息不是名称的一部分,并且仍然保证历史不变,并允许“稍后修改评论”的事情就会很容易。
但是我没有。
其中一部分纯粹是“内部一致性”。 Git只是一个简洁的系统,感谢所有被SHA1保护的对象,并且所有的对象都被视为相同的,而不pipe对象的types如何。 是的,有四种不同的对象,它们都是非常不同的,它们不能以相同的方式使用,但是同时,即使它们的编码在磁盘上可能不同, 从概念上讲,它们也都是完全正确的一样。
但是内部的一致性并不是真正的缺乏灵活性的借口,显然如果我们能够在错误发生后立即纠正错误,这将是非常灵活的。 所以这不是一个很强的论据。
git不允许你改变提交信息的真正原因很简单:这样,你可以信任这些信息。 如果你之后允许人们改变它们,这些信息本质上不是很可靠。
要完成,你可以重写你的本地提交历史logging,以反映你想要的东西,正如sykora所build议的 (有一些重新设置和重置 – hard,gasp!)
但是,一旦你再次发布修改过的历史logging(使用git push origin +master:master
,强制推送发生的+
符号,即使它不会导致“快进”提交) 陷入一些麻烦 。
从这个其他SO问题中提取:
实际上,我曾经把它推到了git.git版本库,并被Linus BIG TIME骂了起来。 这会给其他人造成很多问题。 一个简单的答案是“不要这样做”。
目前一个gitreplace可能会伎俩。
详细说明:创build一个临时工作分支
git checkout -b temp
重置为提交以replace
git reset --hard <sha1>
用正确的信息修改提交
git commit --amend -m "<right message>"
用新的replace旧的提交
git replace <old commit sha1> <new commit sha1>
回到你所在的分支
git checkout <branch>
删除临时分支
git branch -D temp
推
guess
完成。
你可以使用git rebase -i
(针对你分支的分支)'i'进行交互。
用r
(或reword
)replace你想改变的提交注释旁边的pick
,保存并退出,这样你就可以进行编辑。
git push
一遍,你就完成了!
假设你有这样一棵树:
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
所有提交从master
到提前946992
的提交,并提交它们,使用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]
现在强制将temp分支推送到远程:
git push --force origin temp:master
最后一步,在本地删除分支master
,将git fetch origin
从服务器中git fetch origin
分支master
,然后切换到分支master
并删除分支机构temp
。
现在,您的本地和远程都将更新所有消息。
在我们的商店,我介绍了添加可识别名称的注释标签来提交不正确的消息,并使用注释作为替代的约定。
尽pipe这不会帮助那些运行偶然的“git log”命令的人,但它确实为我们提供了一种修复注释中不正确的bug跟踪器引用的方法,我所有的构build和发布工具都能理解这个约定。
这显然不是一个通用的答案,但可能是人们可以在特定社区内采用的东西。 我敢肯定,如果这是一个更大的规模,某种瓷器的支持可能会出现,最终…
(来自http://git.or.cz/gitwiki/GitTips#head-9f87cd21bcdf081a61c29985604ff4be35a5e6c0 )
如何在历史上更深入地改变提交
由于Git中的历史logging是不可变的,除了最近的提交(不是分支头部的提交)之外的任何修改都要求历史logging从改变的提交改写并转发。
您可以使用StGIT,必要时初始化分支,取消提交您想要更改的提交,根据需要popup,更改然后刷新补丁(如果您想更正提交消息,则使用-e选项),然后按一切和stg提交。
或者你可以使用rebase来做到这一点。 创build新的临时分支,使用git reset –hard将其倒回到您想要更改的提交中,更改该提交(它将位于当前头的顶部),然后使用git rebase –onto重新绑定分支。
或者你可以使用git rebase –interactive,它允许各种修改,如补丁重新sorting,崩溃,…
我认为这应该回答你的问题。 但是,请注意,如果您已经将代码推送到远程存储库,并且人们已经从中取出了代码,那么这将会弄乱他们的代码历史以及他们所做的工作。 所以要小心。