如何在git中编辑错误的提交消息(已推送)?


Answers:


125

来自Linus Torvalds的消息可能会回答您的问题:

修改/编辑旧的提交消息

简短的回答:您不能(如果被推动)。


提取(Linus将BitKeeper称为BK):

附带说明,仅出于历史意义:在BK中可以。

而且,如果您习惯了(像我一样),那真的很实用。我会使用安德鲁的贴片炸弹,发现有问题,然后在推出之前对其进行编辑。

我可以用git做同样的事情。使提交消息不成为名称的一部分已经足够容易了,并且仍然可以保证历史记录没有被修改,并允许“以后修改注释”。

但是我没有。

它的一部分纯粹是“内部一致性”。 由于所有对象都受到SHA1保护,并且所有对象(无论对象类型如何)都得到相同的对待,因此Git只是一个更清洁的系统。是的,有四种不同的对象,它们实际上是完全不同的,它们不能以相同的方式使用,但是同时,即使它们在磁盘的编码可能不同,从概念上讲,它们也都可以正常工作相同。

但是内部一致性并不是变硬的真正借口,显然,如果我们能够在错误发生后立即纠正错误,那么内部一致性将非常灵活。因此,这并不是一个很强的论点。

git不允许您更改提交消息的真正原因非常简单:这样,您就可以信任消息。如果您允许人们事后进行更改,则这些消息本来就不是很值得信赖。


为了完整起见,您可以按照sykora的建议重写本地提交历史记录,以反映您想要的内容(进行一些重新设置并重新设置--hard,喘不过气来!)

然而,一旦您发布修订后的历史再次(用git push origin +master:master时,+发生符号迫使推,即使它不会导致一个“快进”提交)......你可能会陷入一些麻烦

从另一个SO问题中提取:

我实际上曾经用--force推送到git.git存储库,并被Linus BIG TIME责骂。这会给其他人带来很多问题。一个简单的答案是“不要这样做”。


好答案。您知道您现在是否能够在较新版本的git中更改已经推送的提交消息吗?自从'09发布以来,有什么变化吗?
David West

@DavidWest同样的道理:您可以重写历史记录并强行推动。
VonC 2014年

2
为了使事情更具体,如果您修改/重置提交,它们的提交标识符(git索引中的十六进制哈希)不可避免地会发生变化;这意味着已编辑的提交与git VCS历史记录中的旧提交有所不同。就是说,如果不幸的是,您的开发团队成员已经撤消了旧提交,则他们不得不撤消已编辑的新提交,并在其本地工作副本中执行新旧合并。
Shigerello 2014年

1
最好重新推送已编辑的提交,以便为您的同事提供方便,从而有利地消除了在同事的工作副本中合并的需要。
Shigerello 2014年

28

目前,使用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

完成。


11
@Jonah:当我尝试推送到远程分支机构时,我会收到一条“最新消息”
Simon Kagwi,2012年

1
如另一个答案中所述:将rebase -i与reword一起使用。并且它将重写历史记录。
西尔万2014年

谢谢您所寻找的解决方案。你节省我的时间!
Tomasz Kuter 2014年

1
@Jonah-我有问题...您的解决方案在本地而非远程更新了我的提交日志。如何将它们推向那里?
Tomasz Kuter 2014年

1
@TomaszKuter,我和你有同样的问题。我的提交消息没有远程更新。我通过使用来自GitHub的以下帮助解决了该问题:help.github.com/articles/changing-a-commit-message。请按照下列步骤操作:修改较早的消息或多个提交消息的部分。基本上,这是user987419从下面给出的答案。如果您已经更改了提交消息,则可以进行选择并保存,而无需再次更改。
evaldeslacasa

19

您可以git rebase -i(针对分支的分支)使用“ i”进行互动。

pick您要更改的提交注释旁边的替换为r(或reword),然后保存并退出,这样便可以进行编辑。

git push 再次,您完成了!


1
这不允许用户在合并提交时编辑消息。使用此命令的某些变体可能吗?
安德鲁·毛

1
尝试合并哪些储备金的-p论点。rebasep
仙人掌

3
我喜欢这个程序,但是起初并不太了解答案。万一有人需要帮助,Githulb的“帮助”页面会提供有关它的详细信息: help.github.com/articles/changing-a-commit-message
evaldeslacasa 2015年

15

假设您有一棵这样的树:

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所有提交都将其提交并提交,如果您还想更改其消息,请使用:946992mastertempamend

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”命令的人员没有帮助,它的确为我们提供了一种方法来修复注释中错误的错误跟踪器引用,并且我所有的构建和发布工具都了解该约定。

这显然不是一个通用的答案,但可能是人们可以在特定社区中采用的。我敢肯定,如果大规模使用它,可能会出现某种形式的瓷质支持,最终……


3
“混帐笔记”可能起到类似的目的
基督教格茨

2

(来自http://git.or.cz/gitwiki/GitTips#head-9f87cd21bcdf081a61c29985604ff4be35a5e6c0

如何改变在历史上更深

由于Git中的历史记录是不可变的,因此要修复除最近的提交(不是分支头的提交)以外的任何内容,都需要从更改后的提交和转发中重写历史记录。

您可以为此使用StGIT,如有必要,初始化分支,取消提交要更改的提交,如有必要,弹出到它,进行更改,然后刷新补丁(如果要更正提交消息,则使用-e选项),然后按一切和stg提交。

或者,您可以使用rebase来做到这一点。创建一个新的临时分支,使用git reset --hard将其倒退到您要更改的提交,更改该提交(它将位于当前文件头的顶部),然后使用git rebase --onto在已更改的提交之上重新设置分支。

或者,您可以使用git rebase --interactive,它允许进行各种修改,例如补丁重新排序,折叠,...

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


理论上的好答案,实践中很危险:请参阅stackoverflow.com/questions/253055#432518
VonC,2009年

0

如果您使用的是Git扩展:进入“提交”屏幕,底部应有一个复选框,其中显示“修改提交”,如下所示:

在此处输入图片说明


@KrunalPandya是的,或者只是按commit&push
batsheva,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.