如何在 git 中编辑不正确的提交消息(我已推送)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/457379/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 06:05:45  来源:igfitidea点击:

How do I edit an incorrect commit message in git ( that I've pushed )?

gitcommit-message

提问by

I want to modify a commit message deeper in history and I've pushed many new commits.

我想修改更深入历史的提交消息,并且我已经推送了许多新的提交。

How do I change the commit message? Is it possible?

如何更改提交消息?是否可以?

回答by VonC

The message from Linus Torvalds may answer your question:

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

Modify/edit old commit messages

修改/编辑旧的提交消息

Short answer: you can not (if pushed).

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



extract (Linus refers to BitKeeper as BK):

提取(Linus 将 BitKeeper 称为 BK):

Side note, just out of historical interest: in BK you could.

And if you're used to it (like I was) it was really quite practical. I would apply a patch-bomb from Andrew, notice something was wrong, and just edit it before pushing it out.

I could have done the same with git. It would have been easy enough to make just the commit message not be part of the name, and still guarantee that the history was untouched, and allow the "fix up comments later" thing.

But I didn't.

Part of it is purely "internal consistency". Git is simply a cleanersystem thanks to everything being SHA1-protected, and all objects being treated the same, regardless of object type. Yeah, there are four different kinds of objects, and they are all really different, and they can't be used in the same way, but at the same time, even if their encoding might be different on disk, conceptuallythey all work exactly the same.

But internal consistency isn't really an excuse for being inflexible, and clearly it would be very flexible if we could just fix up mistakes after they happen. So that's not a really strong argument.

The realreason git doesn't allow you to change the commit message ends up being very simple: that way, you can trust the messages. If you allowed people to change them afterwards, the messages are inherently not very trustworthy.

旁注,只是出于历史兴趣:在 BK 你可以。

如果你习惯了(就像我一样),它真的很实用。我会应用 Andrew 的补丁炸弹,注意到有什么地方不对劲,然后在推出之前对其进行编辑。

我可以用 git 做同样的事情。让提交消息不成为名称的一部分已经很容易了,并且仍然保证历史没有受到影响,并允许“稍后修复评论”。

但我没有。

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

但内部一致性并不是不灵活的真正借口,显然如果我们能在错误发生后纠正错误,那将是非常灵活的。所以这不是一个非常有力的论据。

git 不允许您更改提交消息的真正原因非常简单:这样,您就可以信任这些消息。如果您允许人们事后更改它们,那么这些消息本质上就不太值得信赖。



To be complete, you couldrewrite your local commit history in order to reflect what you want, as suggested by sykora(with some rebase and reset --hard, gasp!)

为了完整起见,您可以按照sykora 的建议重写本地提交历史记录以反映您想要的内容(使用一些 rebase 和 reset --hard,喘气!)

However, once you publish your revised history again(with a git push origin +master:master, the +sign forcing the push to occur, even if it doesn't result in a "fast-forward" commit)... you might get into some trouble.

但是,一旦您再次发布修改后的历史记录(带有git push origin +master:master+强制推送发生的标志,即使它不会导致“快进”提交)……您可能会遇到一些麻烦

Extract from this other SO question:

从另一个 SO 问题中摘录:

I actually once pushed with --force to git.git repository and got scolded by Linus BIG TIME. It will create a lot of problems for other people. A simple answer is "don't do it".

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

回答by Johan

Currently a git replacemight do the trick.

目前git 替换可能会解决问题。

In detail: Create a temporary work branch

详细:创建一个临时工作分支

git checkout -b temp

Reset to the commit to replace

重置为要替换的提交

git reset --hard <sha1>

Amend the commit with the right message

使用正确的消息修改提交

git commit --amend -m "<right message>"

Replace the old commit with the new one

用新提交替换旧提交

git replace <old commit sha1> <new commit sha1>

go back to the branch where you were

回到你所在的分行

git checkout <branch>

remove temp branch

删除临时分支

git branch -D temp

push

guess

done.

完毕。

回答by Marcus

You can use git rebase -i(against the branch you branched from) 'i' for interactive.

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

Replace the picknext to the commit comment you wish to change with r(or reword), save and exit and upon doing so you'll be able to make the edit.

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

git pushonce again and you're done!

git push再一次,你就完成了!

回答by Huy Vo

Suppose you have a tree like this:

假设你有一棵树是这样的:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]

First, checkouta temp branch:

首先,checkout一个临时分支:

git checkout -b temp

On tempbranch, reset --hardto a commit that you want to change its message (for example, that commit is 946992):

temp分支上,reset --hard对于要更改其消息的提交(例如,该提交是946992):

git reset --hard 946992

Use amendto change the message:

使用amend更改消息:

git commit --amend -m "<new_message>"

After that the tree will look like this:

之后,树将如下所示:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
           \
            b886a0 [temp]

Then, cherry-pickall the commit that is ahead of 946992from masterto tempand commit them, use amendif you want to change their messages as well:

然后,cherry-pick946992from masterto之前的所有提交temp并提交它们,amend如果您还想更改它们的消息,请使用:

git cherry-pick 9143a9
git commit --amend -m "<new_message>
...
git cherry-pick 5a6057
git commit --amend -m "<new_message>

The tree now looks like this:

这棵树现在看起来像这样:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
               \
                b886a0 - 41ab2c - 6c2a3s - 7c88c9 [temp]

Now force push the temp branch to remote:

现在强制将临时分支推送到远程:

git push --force origin temp:master

The final step, delete branch masteron local, git fetch originto pull branch masterfrom the server, then switch to branch masterand delete branch temp.

最后一步,master在本地删除分支,从服务器git fetch origin拉取分支master,然后切换到分支master并删除分支temp

Now both your local and remote will have all the messages updated.

现在您的本地和远程都将更新所有消息。

回答by Christian Goetze

At our shop, I introduced the convention of adding recognizably named annotated tags to commits with incorrect messages, and using the annotation as the replacement.

在我们的商店,我介绍了将可识别命名的带注释的标签添加到带有错误消息的提交的约定,并使用注释作为替换。

Even though this doesn't help folks who run casual "git log" commands, it does provide us with a way to fix incorrect bug tracker references in the comments, and all my build and release tools understand the convention.

尽管这对运行随意的“git log”命令的人没有帮助,但它确实为我们提供了一种方法来修复注释中错误的错误跟踪器引用,并且我所有的构建和发布工具都理解约定。

This is obviously not a generic answer, but it might be something folks can adopt within specific communities. I'm sure if this is used on a larger scale, some sort of porcelain support for it may crop up, eventually...

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

回答by sykora

(From http://git.or.cz/gitwiki/GitTips#head-9f87cd21bcdf081a61c29985604ff4be35a5e6c0)

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

How to change commits deeper in history

Since history in Git is immutable, fixing anything but the most recent commit (commit which is not branch head) requires that the history is rewritten from the changed commit and forward.

You can use StGIT for that, initialize branch if necessary, uncommitting up to the commit you want to change, pop to it if necessary, make a change then refresh patch (with -e option if you want to correct commit message), then push everything and stg commit.

Or you can use rebase to do that. Create new temporary branch, rewind it to the commit you want to change using git reset --hard, change that commit (it would be top of current head), then rebase branch on top of changed commit, using git rebase --onto .

Or you can use git rebase --interactive, which allows various modifications like patch re-ordering, collapsing, ...

如何更改更深入历史的提交

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

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

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

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

I think that should answer your question. However, note that if you have pushedcode to a remote repository and people have pulled from it, then this is going to mess up their code histories, as well as the work they've done. So do it carefully.

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

回答by batsheva

If you are using Git Extensions: go into the Commit screen, there should be a checkbox that says "Amend Commit" at the bottom, as can be seen below:

如果您正在使用 Git 扩展:进入 Commit 屏幕,底部应该有一个复选框,上面写着“Amend Commit”,如下所示:

enter image description here

在此处输入图片说明