如何修改旧的 Git 提交?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8824971/
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 12:43:20  来源:igfitidea点击:

How to amend older Git commit?

gitversion-controlgit-rewrite-history

提问by michael

I have made 3 git commits, but have not been pushed. How can I amend the older one (ddc6859af44) and (47175e84c) which is not the most recent one?

我已经进行了 3 次 git 提交,但没有被推送。我如何修改旧的 (ddc6859af44) 和 (47175e84c) 不是最新的?

$git log
commit f4074f289b8a49250b15a4f25ca4b46017454781
Date:   Tue Jan 10 10:57:27 2012 -0800

commit ddc6859af448b8fd2e86dd0437c47b6014380a7f
Date:   Mon Jan 9 16:29:30 2012 -0800

commit 47175e84c2cb7e47520f7dde824718eae3624550
Date:   Mon Jan 9 13:13:22 2012 -0800

回答by Adam Dymitruk

git rebase -i HEAD^^^

Now mark the ones you want to amend with editor e(replace pick). Now save and exit.

现在标记您要修改的内容edite(替换pick)。现在保存并退出。

Now make your changes, then

现在进行更改,然后

git add .
git rebase --continue

If you want to add an extra delete remove the options from the commit command. If you want to adjust the message, omit just the --no-editoption.

如果要添加额外的删除,请从 commit 命令中删除选项。如果要调整消息,请仅省略该--no-edit选项。

回答by akostadinov

I prepared my commit that I wanted to amend with an older one and was surprised to see that rebase -i complained that I have uncommitted changes. But I didn't want to make my changes again specifying edit option of the older commit. So the solution was pretty easy and straightforward:

我准备了我想用旧的提交修改的提交,并惊讶地看到 rebase - 我抱怨我有未提交的更改。但我不想再次进行更改,指定旧提交的编辑选项。所以解决方案非常简单明了:

  1. prepare your update to older commit, add it and commit
  2. git rebase -i <commit you want to amend>^- notice the ^so you see the said commit in the text editor
  3. you will get sometihng like this:

    pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync
    pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies
    pick e23d23a fix indentation of jgroups.xml
    
  4. now to combine e23d23a with 8c83e24 you can change line order and use squash like this:

    pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync    
    squash e23d23a fix indentation of jgroups.xml
    pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies
    
  5. write and exit the file, you will be present with an editor to merge the commit messages. Do so and save/exit the text document

  6. You are done, your commits are amended
  1. 准备对旧提交的更新,添加并提交
  2. git rebase -i <commit you want to amend>^- 注意^所以你会在文本编辑器中看到所说的提交
  3. 你会得到这样的东西:

    pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync
    pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies
    pick e23d23a fix indentation of jgroups.xml
    
  4. 现在要将 e23d23a 与 8c83e24 结合起来,您可以更改行顺序并像这样使用壁球:

    pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync    
    squash e23d23a fix indentation of jgroups.xml
    pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies
    
  5. 写入并退出文件,您将看到一个编辑器来合并提交消息。这样做并保存/退出文本文档

  6. 你完成了,你的提交被修改了

credit goes to: http://git-scm.com/book/en/Git-Tools-Rewriting-HistoryThere's also other useful demonstrated git magic.

归功于:http: //git-scm.com/book/en/Git-Tools-Rewriting-History还有其他有用的演示 git 魔法。

回答by Benjamin Bannier

You could can use git rebaseto rewrite the commit history. This can be potentially destructive to your changes, so use with care.

您可以使用git rebase来重写提交历史记录。这可能会对您的更改造成潜在破坏,因此请谨慎使用。

First commit your "amend" change as a normal commit. Then do an interactive rebase starting on the parent of your oldest commit

首先将您的“修改”更改作为正常提交提交。然后从最旧提交的父级开始进行交互式变基

git rebase -i 47175e84c2cb7e47520f7dde824718eae3624550^

This will fire up your editor with all commits. Reorder them so your "amend" commit comes below the one you want to amend. Then replace the first word on the line with the "amend" commit with swhich will combine (squash) it with the commit before. Save and exit your editor and follow the instructions.

这将通过所有提交启动您的编辑器。重新排序它们,以便您的“修改”提交低于您要修改的提交。然后将行上的第一个单词替换为“amend”提交,它将与之前的提交s组合(squash)它。保存并退出编辑器并按照说明进行操作。

回答by Melebius

I've used another way for a few times. In fact, it is a manual git rebase -iand it is useful when you want to rearrange several commits including squashing or splitting some of them. The main advantage is that you don't have to decide about every commit's destiny at a single moment. You'll also have all Git features available during the process unlike during a rebase. For example, you can display the log of both original and rewritten history at any time, or even do another rebase!

我用另一种方法几次。事实上,它是一本手册git rebase -i,当您想重新排列多个提交(包括压缩或拆分其中的一些)时,它很有用。主要优点是您不必在一个时刻决定每个提交的命运。与变基期间不同,您还将在此过程中使用所有 Git 功能。例如,您可以随时显示原始历史和重写历史的日志,甚至可以再做一次 rebase!

I'll refer to the commits in the following way, so it's readable easily:

我将通过以下方式引用提交,因此它很容易阅读:

C # good commit after a bad one
B # bad commit
A # good commit before a bad one

Your history in the beginning looks like this:

你一开始的历史是这样的:

x - A - B - C
|           |
|           master
|
origin/master

We'll recreate it to this way:

我们将以这种方式重新创建它:

x - A - B*- C'
|           |
|           master
|
origin/master

Procedure

程序

git checkout B       # get working-tree to the state of commit B
git reset --soft A   # tell Git that we are working before commit B
git checkout -b rewrite-history   # switch to a new branch for alternative history

Improve your old commit using git add(git add -i, git stashetc.) now. You can even split your old commit into two or more.

提高你的旧提交使用git addgit add -igit stash等等)现在。您甚至可以将旧提交拆分为两个或多个。

git commit           # recreate commit B (result = B*)
git cherry-pick C    # copy C to our new branch (result = C')

Intermediate result:

中间结果:

x - A - B - C 
|    \      |
|     \     master
|      \
|       B*- C'
|           |
|           rewrite-history
|
origin/master

Let's finish:

让我们完成:

git checkout master
git reset --hard rewrite-history  # make this branch master

That's it, you can pushyour progress now.

就是这样,你push现在可以进步了。

回答by Avi

You can use git rebase --interactive, using the editcommand on the commit you want to amend.

您可以使用git rebase --interactive,edit在要修改的提交上使用命令。

回答by Adam Dymitruk

In case the OP wants to squash the 2 commits specified into 1, here is an alternate way to do it without rebasing

如果 OP 想要将指定的 2 个提交压缩为 1,这里有另一种方法来做到这一点,而无需重新定位

git checkout HEAD^               # go to the first commit you want squashed
git reset --soft HEAD^           # go to the second one but keep the tree and index the same
git commit --amend -C HEAD@{1}   # use the message from first commit (omit this to change)
git checkout HEAD@{3} -- .       # get the tree from the commit you did not want to touch
git add -A                       # add everything
git commit -C HEAD@{3}           # commit again using the message from that commit

The @{N)syntax is handy to know as it will allow you to reference the history of where your references were. In this case it's HEAD which represents your current commit.

@{N)语法是很方便的知道,因为它可以让你引用的地方你的推荐人的历史。在这种情况下,它是代表您当前提交的 HEAD。