我如何在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,崩溃,…

我认为这应该回答你的问题。 但是,请注意,如果您已经代码送到远程存储库,并且人们已经从中取出了代码,那么这将会弄乱他们的代码历史以及他们所做的工作。 所以要小心。