使用 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
Edit a merge commit with git rebase
提问by vasekch
In Git when I have commits eg. A - B - C
and I want to edit the B
commit, I
在 Git 中,当我提交时,例如。A - B - C
我想编辑B
提交,我
- use
git rebase -i <A-commit-hash>
, - in the list I write
edit
command in front ofB
commit, - git rebase stops right after
B
commit so I can fix anything I want usinggit commit --amend
, - and then I continue using
git rebase --continue
.
- 使用
git rebase -i <A-commit-hash>
, - 在我
edit
在B
提交前写命令的列表中, - 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 -p
flag 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 rebase
to stop at a merge commit. The git rebase -p -i <blah>
list ignores merge commits, so I cannot write edit
command in front of it and make the git rebase
stop 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 -p
option uses the -i
mechanism internally, so mixing the two doesn't really work.
当涉及合并时,Git 并不能轻松地进行交互式变基。该-p
选项在-i
内部使用该机制,因此将两者混合并不能真正起作用。
However, git rebase
is 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:
这是我建议的方法:
- use
git rebase
to get to the commit afterthe merge (the child of the merge) - use
git reset --hard HEAD^
to manually get to the merge - use
git commit --amend
to repair the merge - use
git cherry-pick
to get back to the commit after the merge - use
git rebase --continue
to finish
- 用于在合并后
git rebase
进行提交(合并的子项) - 用于
git reset --hard HEAD^
手动进入合并 - 用于
git commit --amend
修复合并 - 用于
git cherry-pick
在合并后返回提交 - 用于
git rebase --continue
完成
Here are the specific steps:
下面是具体步骤:
- Note the SHA1 ID of the merge commit you want to modify. For discussion, suppose it is
deadbeef
. - 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
. - Run
git rebase -i deadbeef
. - Select
facef00d
for editing. - When rebase returns you to a prompt to edit
facef00d
, rungit reset --hard HEAD^
. You should now be atdeadbeef
(git rev-parse HEAD
should printdeadbeef
). - Make your edits to fix the incorrect merge conflict and use
git add
to stage them. - Run
git commit --amend
to fuse the staged fix with the bad merge commit. The result will now have a different SHA1 (notdeadbeef
). - Run
git cherry-pick facef00d
to apply the changes made byfacef00d
to the fixed merge commit. - Run
git rebase --continue
to finish.
- 请注意要修改的合并提交的 SHA1 ID。为了讨论,假设它是
deadbeef
。 - 请注意在您要修改的合并提交(合并提交的子项)之后提交的 SHA1 ID。假设是
facef00d
。 - 运行
git rebase -i deadbeef
。 - 选择
facef00d
进行编辑。 - 当 rebase 返回到编辑提示时
facef00d
,运行git reset --hard HEAD^
. 你现在应该在deadbeef
(git rev-parse HEAD
应该打印deadbeef
)。 - 进行编辑以修复不正确的合并冲突并用于
git add
暂存它们。 - 运行
git commit --amend
以将分阶段修复与错误的合并提交融合。结果现在将具有不同的 SHA1(不是deadbeef
)。 - 运行
git cherry-pick facef00d
以将所做的更改应用于facef00d
固定的合并提交。 - 运行
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-merges
option available in Git 2.22 and above. This option preserves the merge topology, and works with interactive rebases.
现在有了--rebase-merges
Git 2.22 及更高版本中可用的选项,这变得容易多了。此选项保留合并拓扑,并与交互式变基一起使用。
It'll look something like this, assuming B
is 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 merge
and the pick
:
您现在可以在和之间插入一个b
(或break
):merge
pick
merge -C B branch-name # Merge branch 'xyz' into whatever
break
pick C
At the break commit --amend
the 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 手册页的变基合并部分。