如何在原始分支中压缩提交后进行重组?

ere*_*ner 13 git rebase git-rebase

我有

A--B--C master
       \
        D branch0
Run Code Online (Sandbox Code Playgroud)

然后,我壁球BCB'.我如何变形branch0,看起来像这样:

A--B' master
    \
     D branch0
Run Code Online (Sandbox Code Playgroud)

Kyl*_*enn 47

当您在分支之间有分支时,在 PR 上使用挤压合并时,我遇到了类似的问题。

我常见的例子是,如果我有一个功能分支 ( feature-a)。我将一些提交推送到该分支。然后我创建另一个功能分支 ( feaure-b-off-a)。然后我压缩合并feature-a到 main 中,我会在 main 的 PR 中看到重复的提交feature-b-off-a

为了解决这个问题,我们可以使用类似于此处rebase --onto接受的答案。但手动工作是寻找(我指的是下面的共同祖先)。另一种方式重写:C

git rebase --onto main common-ancestor feature-b-off-a

  • common-ancestor获取和之间的所有提交feature-b-off-a并将它们重新定位到main

幸运的是,git有一种方法可以找到两个分支之间的共同祖先:

git merge-base feature-b-off-a feature-a


长话短说:

# This will print out the 'common-ancestor' commit between the commits/branches causing the problem
git merge-base feature-b-off-a feature-a
# Take all the commits between common-ancestor and feature-b-off-a and rebase them onto main
git rebase --onto main <common-ancestor> feature-b-off-a
# Then you'll need to force push since it's a rebase
git push -f origin feature-b-off-a
Run Code Online (Sandbox Code Playgroud)

您对 main 的 PR 现在应该只显示新的提交。


奖金 git-alias

注意:这假设您的流程将两者压缩合并为main

git config --global alias.rebase-onto '!f() { git rebase --onto main $(git merge-base "$1" "$2") "$1"; }; f'
Run Code Online (Sandbox Code Playgroud)

您可以使用以下方式调用:

git rebase-onto feature-b-off-a feature-a
# Then you'll need to force push since it's a rebase
git push -f origin feature-b-off-a
Run Code Online (Sandbox Code Playgroud)


小智 19

使用--onto参数git rebase,它改变了git重放工作的基线.

git checkout branch0
Run Code Online (Sandbox Code Playgroud)

在这种状态下,你仍然应该在你的git历史中看到C.

git rebase --onto B' C
Run Code Online (Sandbox Code Playgroud)

这转换为:自提交C以来我的当前分支中的所有提交(在您的情况下只是D)并在B'之上回放

您还可以使用可选<branch>参数同时执行checkout和rebase:

git rebase --onto B' C branch0
Run Code Online (Sandbox Code Playgroud)

  • 没有结账(较短): `git rebase --onto master Cbranch0` (2认同)
  • 值得澄清的是,“自提交 C”是排他的,即,这应该是您希望重播的第一个提交之前的一个提交。 (2认同)