我有
A--B--C master
\
D branch0
然后我将
B
和 C
压入 B'
。
我如何重新设置 branch0
使其看起来像这样:
A--B' master
\
D branch0
使用
--onto
参数到 git rebase
,这会更改 git 重放工作的基线。
git checkout branch0
在此状态下,您应该仍会在 git 历史记录中看到 C。
git rebase --onto B' C
这意味着:获取自提交C以来我当前分支中的所有提交(在您的情况下,这只是D)并在B'
之上回放您还可以使用可选的
<branch>
参数一次执行签出和变基操作:
git rebase --onto B' C branch0
当你的分支与分支之间存在分支时,我在 PR 上使用挤压合并时遇到了类似的问题。
我常见的例子是,如果我有一个功能分支 (
feature-a
)。我将一些提交推送到该分支。然后我创建另一个功能分支(feaure-b-off-a
)。然后我将 feature-a
压缩合并到 main 中,我会在 feature-b-off-a
的 PR 中看到重复提交到 main 中。
要解决此问题,我们可以使用
rebase --onto
,就像已接受的答案,here。但手动工作是找到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
注意:这假设您的流程将两者挤压合并为
main
git config --global alias.rebase-onto '!f() { git rebase --onto main $(git merge-base "$1" "$2") "$1"; }; f'
您拨打电话的方式:
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
我能想到的一个快速方法是,
git checkout branch0
记下
git log
的 D 提交的 sha
git checkout master
现在将branch0重命名为branch1
git branch -m branch0 branch1
A--B' master
\
D branch1
现在删除branch1
git branch -D branch1
再次创建branch0,如下。
git checkout -b branch0
A--B' - master&branch0
上述命令后master和branch0是相同的。我们需要在branch0 中进行的唯一更改就是获取提交D。
git cherry-pick D
现在branch0看起来如下
A--B' master
\
D branch0