使用 git rebase 编辑合并提交

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

Edit a merge commit with git rebase

gitrebase

提问by vasekch

In Git when I have commits eg. A - B - Cand I want to edit the Bcommit, I

在 Git 中,当我提交时,例如。A - B - C我想编辑B提交,我

  • use git rebase -i <A-commit-hash>,
  • in the list I write editcommand in front of Bcommit,
  • git rebase stops right after Bcommit so I can fix anything I want using git commit --amend,
  • and then I continue using git rebase --continue.
  • 使用git rebase -i <A-commit-hash>
  • 在我editB提交前写命令的列表中,
  • git rebase 在B提交后立即停止,所以我可以修复我想要使用的任何东西git commit --amend
  • 然后我继续使用git rebase --continue.

As far as I know this is the best practice how to do this. With this method I can edit any commit in the past (as long as it hasn't been pushed to remote branch yet), and moreover with -pflag I can even preserve the merges. This is just great.

据我所知,这是如何做到这一点的最佳实践。使用这种方法,我可以编辑过去的任何提交(只要它尚未推送到远程分支),而且使用-p标志我什至可以保留合并。这太棒了。

My current problem is: I did a mistake (typo) on one line in a merge commit (while resolving a conflict when merging two branches).

我目前的问题是:我在合并提交中的一行上犯了一个错误(错字)(同时在合并两个分支时解决了冲突)。

I'd like to fix it but I don't know how to make git rebaseto stop at a merge commit. The git rebase -p -i <blah>list ignores merge commits, so I cannot write editcommand in front of it and make the git rebasestop there to let me edit it.

我想修复它,但我不知道如何git rebase停止合并提交。该git rebase -p -i <blah>列表忽略合并提交,所以我不能edit在它前面写命令并在git rebase那里停下来让我编辑它。

Any help please? I just want to fix this line in the merge commit while preserving all the commits (and merges) after it.

请问有什么帮助吗?我只想在合并提交中修复这一行,同时保留它之后的所有提交(和合并)。

Thanks.

谢谢。

回答by Richard Hansen

Git does not make it easy to do interactive rebases when merges are involved. The -poption uses the -imechanism internally, so mixing the two doesn't really work.

当涉及合并时,Git 并不能轻松地进行交互式变基。该-p选项在-i内部使用该机制,因此将两者混合并不能真正起作用。

However, git rebaseis just an automated way to do lots of cherry-picks. You can replicate its behavior by manually cherry-picking to get a bit more control over the process. It's less convenient and more prone to human error, but possible.

然而,git rebase这只是一种进行大量挑选的自动化方式。您可以通过手动挑选来复制其行为,以更好地控制该过程。它不太方便,更容易出现人为错误,但有可能。

This is the approach I suggest:

这是我建议的方法:

  1. use git rebaseto get to the commit afterthe merge (the child of the merge)
  2. use git reset --hard HEAD^to manually get to the merge
  3. use git commit --amendto repair the merge
  4. use git cherry-pickto get back to the commit after the merge
  5. use git rebase --continueto finish
  1. 用于在合并git rebase进行提交(合并的子项)
  2. 用于git reset --hard HEAD^手动进入合并
  3. 用于git commit --amend修复合并
  4. 用于git cherry-pick在合并后返回提交
  5. 用于git rebase --continue完成

Here are the specific steps:

下面是具体步骤:

  1. Note the SHA1 ID of the merge commit you want to modify. For discussion, suppose it is deadbeef.
  2. Note the SHA1 ID of the commit right after the merge commit you want to modify (the merge commit's child). Suppose it is facef00d.
  3. Run git rebase -i deadbeef.
  4. Select facef00dfor editing.
  5. When rebase returns you to a prompt to edit facef00d, run git reset --hard HEAD^. You should now be at deadbeef(git rev-parse HEADshould print deadbeef).
  6. Make your edits to fix the incorrect merge conflict and use git addto stage them.
  7. Run git commit --amendto fuse the staged fix with the bad merge commit. The result will now have a different SHA1 (not deadbeef).
  8. Run git cherry-pick facef00dto apply the changes made by facef00dto the fixed merge commit.
  9. Run git rebase --continueto finish.
  1. 请注意要修改的合并提交的 SHA1 ID。为了讨论,假设它是deadbeef
  2. 请注意在您要修改的合并提交(合并提交的子项)之后提交的 SHA1 ID。假设是facef00d
  3. 运行git rebase -i deadbeef
  4. 选择facef00d进行编辑。
  5. 当 rebase 返回到编辑提示时facef00d,运行git reset --hard HEAD^. 你现在应该在deadbeefgit rev-parse HEAD应该打印deadbeef)。
  6. 进行编辑以修复不正确的合并冲突并用于git add暂存它们。
  7. 运行git commit --amend以将分阶段修复与错误的合并提交融合。结果现在将具有不同的 SHA1(不是deadbeef)。
  8. 运行git cherry-pick facef00d以将所做的更改应用于facef00d固定的合并提交。
  9. 运行git rebase --continue到结束。

回答by i3ensays

May be easier to create a fixup commit 'D' then use 'git rebase -p -i <blah>' to reorder 'D' right after 'B' and squash it into 'B'.

创建修复提交 'D' 然后使用 ' git rebase -p -i <blah>' 在 'B' 之后重新排序 'D' 并将其压缩为 'B'可能更容易。

pick A
pick B  <- merge commit to ammend
fixup D
pick C

回答by Raman

This is much easier now with the --rebase-mergesoption available in Git 2.22 and above. This option preserves the merge topology, and works with interactive rebases.

现在有了--rebase-mergesGit 2.22 及更高版本中可用的选项,这变得容易多了。此选项保留合并拓扑,并与交互式变基一起使用。

It'll look something like this, assuming Bis the merge commit to amend:

它看起来像这样,假设B是要修改的合并提交:

label onto

... some branch definitions ...

reset onto
merge -C B branch-name # Merge branch 'B' into whatever
pick C

You can now insert a b(or break) in between the mergeand the pick:

您现在可以在和之间插入一个b(或break):mergepick

merge -C B branch-name # Merge branch 'xyz' into whatever
break
pick C

At the break commit --amendthe merge, and then continue the rebase.

在中断commit --amend合并,然后继续变基。

This also works with a fixup commit. For example, lets say the commit with the fix for the merge is D. You can move your fixup commit D to immediately after the merge commit:

这也适用于修复提交。例如,假设带有合并修复程序的提交是D. 您可以在合并提交后立即将修复提交 D 移动到:

merge -C B branch-name # Merge branch 'xyz' into whatever
fixup D
pick C

See the Rebasing Mergessection of the git-merge man page.

请参阅git-merge 手册页的变基合并部分。