推送后更改git commit消息(假设没有人从远程拉出)


981

我做了一个git commit和随后的推送。我想更改提交消息。如果我理解正确,那么这是不可取的,因为有人在进行此类更改之前可能已经从远程存储库中拉出了。如果我知道没人拉怎么办?

有没有办法做到这一点?


你尝试了什么?假设您已经知道如何更改提交消息,然后尝试进行推送,Git会告诉您需要做些什么才能使其实现。
安德鲁·马歇尔

1
请参阅问题“我如何在git中编辑错误的提交消息(已推送)”的答案?stackoverflow.com/a/457396/444639
Mike Rylander 2013年

4
声明-Google问题git commit排名第一!
Manish Shrivastava'5


如果您修改HEAD提交并通常(不使用--force)推送,那么令人惊讶的是它不会失败。HEAD提交消息将使用更改后的提交ID进行更新。这意味着除HEAD以外的其他提交ID保持不变。我注意到git 2.8.1版本存在这种行为。
irsis

Answers:


1370

改变历史

如果这是最新的提交,则可以执行以下操作:

git commit --amend

这将使编辑器显示最后的提交消息,并允许您编辑消息。(-m如果您要清除旧消息并使用新消息,则可以使用。)

推动

然后,当您按下按钮时,请执行以下操作:

git push --force-with-lease <repository> <branch>

或者,您可以使用“ +”:

git push <repository> +<branch>

或者您可以使用--force

git push --force <repository> <branch>

使用这些命令时要小心。

  • 如果其他人将更改推送到同一分支,则可能要避免破坏这些更改。该--force-with-lease选项是最安全的,因为如果有任何上游更改,它将中止(

  • 如果您未明确指定分支,则Git将使用默认的推送设置。如果您的默认推送设置为“匹配”,则您可能会同时破坏多个分支上的更改。

之后拉/取

现在,任何已经拉出的人都会收到一条错误消息,并且他们需要通过执行以下操作来更新(假设他们自己没有进行任何更改):

git fetch origin
git reset --hard origin/master # Loses local commits

使用时要小心reset --hard。如果分支有更改,这些更改将被销毁。

有关修改历史记录的注释

被破坏的数据实际上只是旧的提交消息,但--force不知道该消息,并且也会很高兴地删除其他数据。因此可以想象--force为“我想销毁数据,并且我肯定知道要销毁哪些数据”。但是,当提交已销毁的数据时,通常可以从reflog中恢复旧的提交-数据实际上是孤立的而不是被销毁的(尽管孤立的提交会定期删除)。

如果您不认为自己要破坏数据,请远离--force…… 可能会发生坏事

这就是为什么--force-with-lease更安全的原因。


13
小心该“修复”,就好像它们有任何本地未推送的提交一样,它们将被“丢失”(失去真正的含义是孤立的,但是恢复它们不是显而易见的)。
安德鲁·马歇尔

1
您可能需要在按下--force时指定分支名称,否则可能会超出预期。
user693960 2013年

1
@ user693960:Git只会推送您配置为推送的内容。
Dietrich Epp

10
只要git push --force没有<库>和<枝>选项工作也一样,如果你有你的上游设置了。
ahnbizcad 2014年

2
你能举一个例子<repository>吗?是originorg/repo?还是只是repo
MikeSchinkel '18

439

说啊 :

git commit --amend -m "New commit message"

然后

git push --force

8
在我的情况下git push origin <BRANCH-NAME>不起作用,我不得不git push --force按照接受的答案中的说明使用。
加百利2014年

1
这对我不起作用。一定要我们git push --force,否则推不成功。
ahnbizcad 2014年

4
@ahnbizcad,它应该可以工作。只需确保分支名称正确即可。
威廉

3
我为您的解释简单而高兴!我使用它的频率更高
Vasikos

3
只有在临时“取消保护”分支(在GitLab托管的项目上发生)之后,我才成功应用这些命令。如果您有此问题,请在应用这些命令之前,请参考此stackoverflow.com/a/32267118/1423345以“取消保护”分支,在修改完提交消息后,可以再次“保护”分支:)
John

261

要编辑最近提交以外的提交:

步骤1git rebase -i HEAD~nn受影响的最后一次提交进行交互式变基。(即,如果您想更改3次提交的提交消息,请执行git rebase -i HEAD~3

git将弹出一个编辑器来处理这些提交,请注意以下命令:

#  r, reword = use commit, but edit the commit message

那正是我们所需要的!

第二步:更改pickr为您要更新的消息,这些提交。请勿在此处更改提交消息,它将被忽略。您将在下一步中进行操作。保存并关闭编辑器。

请注意,如果您编辑了重新设定的“计划”,但它没有开始让您重命名文件的过程,请运行:

git rebase --continue

如果要更改用于交互式会话的文本编辑器(例如,从默认的vi更改为nano),请运行:

GIT_EDITOR=nano git rebase -i HEAD~n

第三步:Git将为您r之前输入的每个修订版本弹出另一个编辑器。根据需要更新提交消息,然后保存并关闭编辑器。

步骤4:更新所有提交消息之后。您可能要git push -f更新遥控器。


21
这应该是可以接受的答案,因为它可以更改除最近提交以外的其他提交,而不同于可以接受的答案。你救了我的日子。谢谢!
xZero

1
为最后3次提交选择n = 3:git rebase -i HEAD~3
HeikoS

如果您编辑了变基的“计划”,但是它还没有开始让您重命名文件的过程,请运行git rebase --continue。并且,如果您想更改用于交互式会话的文本编辑器(例如,从默认更改vinano),请运行GIT_EDITOR=nano git rebase -i HEAD~n
杰米·伯奇

我对此进行了编辑,以添加更多信息。请看一下。这是我想要做的事情的答案,但是我滚动了它,因为它没有标题。
基普(Kip)

我进行了建议的编辑,以将@JamieBirch中的有用评论放入答案中,可能需要复审。
Notts90


19

应该注意的是,如果您使用多个push --force引用,那么它们将全部被修改。确保注意您的git repo配置为推送到的位置。幸运的是,有一种方法可以通过指定要更新的单个分支来稍微保护该过程。从git手册页中读取:

请注意--force适用于所有推送的ref,因此将push.default设置为match或与配置了remote的多个推送目标一起使用它。*。push可能会覆盖当前分支以外的其他ref(包括本地ref严格落后于他们的远程对象)。要强制只推送到一个分支,请在refspec前面使用+进行推送(例如git push origin + master强制推送到master分支)。


3
非常重要的说明。
peterh-恢复莫妮卡

强制答案均不适合我,因为我在服务器上没有ForcePush权限。相反,我想执行一个更改以前的提交消息的提交。我可以在该提交的注释部分写“提交消息已更改”。
nurettin

11

如果要修改旧的提交,而不是最后一个,则需要使用rebase命令,在这里解释,Github上帮助页面,在修改的旧或多个消息提交信息部分


11

命令1

git commit --amend -m "New and correct message"

然后,

命令2

git push origin --force

8
git commit --amend

然后在当前窗口中编辑和更改消息。在那之后

git push --force-with-lease

2

另一个选择是创建一个附加的“勘误提交”(并推送),该引用引用包含错误的提交对象-新的勘误提交也提供了更正。勘误提交是指没有实质性代码更改而是重要的提交消息的提交-例如,在您的自述文件中添加一个空格字符,然后使用重要的提交消息来提交更改,或者使用git选项--allow-empty。它肯定比重定基础更容易,更安全,它不会修改真实的历史记录,并且可以使分支树保持干净(使用amend如果您要更正最新的提交,它也是一个不错的选择,但是对于较早的提交,勘误提交可能是一个不错的选择)。这种事情很少发生,仅记录错误就足够了。将来,如果您需要在git日志中搜索功能关键字,则可能不会出现原始(错误)提交,因为该原始提交(原始错字)使用了错误的关键字-但是,该关键字会出现在勘误提交中,然后将您指向具有错字的原始提交。这是一个例子:

$ git日志
提交0c28141c68adae276840f17ccd4766542c33cf1d
作者:先到后 
日期:2018年8月8日星期三15:55:52 2018-06-06

    勘误提交:
    该提交没有实质性的代码更改。
    提供此提交仅是为了记录对先前提交消息的更正。
    这涉及提交对象e083a7abd8deb5776cb304fa13731a4182a24be1
    原始不正确的提交消息:
        将背景色更改为红色
    校正(*更改突出显示*):
        将背景色更改为*蓝色*

提交032d0ff0601bff79bdef3c6f0a02ebfa061c4ad4
作者:先到后 
日期:2018年8月8日星期三15:43:16 -0600

    一些临时提交消息

提交e083a7abd8deb5776cb304fa13731a4182a24be1
作者:先到后 
日期:2018年8月8日星期三13:31:32 2018-0600

    将背景色更改为红色

抢,这看起来很有希望。您可以显示执行“勘误提交”所需的命令吗?这些条款仅在Google上显示。
吉姆(Jim)

1
“勘误提交”只是带有消息的正常提交,该消息引用了先前的错误提交,记录并提供了对先前错误的更正。 git commit -m “fixed feature A”(让我们假设git为它提供了一个提交ID e3ab7312 ......(后来您意识到您的消息是不正确的,所以现在对文件进行无关紧要的更改,例如在自述文件中添加一个空格,或者使用—allow-emptygit选项)。 .. git commit -m “Errata commit for previous commit e3ab7312... original message should have been ‘fixed feature *B*’''”
rob_7cc

1
...如果以后需要在git日志中搜索对“功能B”的引用,则会显示勘误提交,但勘误提交消息中包含对原始提交ID的引用,该ID提供了完全的可追溯性。顺便说一句,“勘误提交”没有什么特别的(git中没有“勘误”命令或选项)...这只是我的常规提交的术语,它可以纠正先前有错误/错误的提交。
rob_7cc

抢,效果很好。我可以使用SHA添加具有正确描述的新空提交,它指向原始提交。现在,两者都显示在模块的“ git链”中。谢谢!
吉姆(Jim)

我很高兴为您工作。我使用相同的技术来纠正提交消息中的错误。另外,我最近才发现git notes 这将与“勘误提交”具有相同的目的。只需在以前的提交中添加注释以注释或更正提交消息中的任何错误: https://git-scm.com/docs/git-notes
rob_7cc,

0

这对我来说很好

git checkout来源/分支名称

如果您已经在分支中,那么最好进行拉动或变基

git pull

要么

git -c core.quotepath=false fetch origin --progress --prune

以后您可以简单地使用

git commit --amend -m "Your message here"

或者,如果您想打开文本编辑器,请使用

git commit --amend

如果您有很多评论,我将更喜欢使用文本编辑器。您可以使用命令设置首选的文本编辑器

git config --global core.editor your_preffered_editor_here

无论如何,当您完成更改提交消息后,保存并退出

然后运行

git push --force

你完成了


0

如果您使用位桶管道,则针对同一问题的其他信息

编辑您的讯息

git commit --amend

推到服务器

git push --force <repository> <branch>

然后将--force添加到管道上的push命令中

git ftp push --force

这将删除您之前的提交并推送您当前的提交。

第一次推动后移除--force

我在bitbucket管道上尝试过它并且工作正常

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.