在原始分支中压缩提交后如何变基?
How to rebase after squashing commits in the original branch?
我有
A--B--C master
\
D branch0
然后我将 B
和 C
压缩成 B'
。
我如何变基 branch0
使其看起来像这样:
A--B' master
\
D branch0
我能想到的一个快速方法是,
git checkout branch0
记下 git log
的 D 提交的 sha
git checkout master
现在将 branch0 重命名为 branch1
git branch -m branch0 branch1
A--B' master
\
D branch1
现在删除分支1
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
将 --onto
参数用于 git 变基,这会更改 git 重放工作的基线。
git checkout branch0
在此状态下,您应该仍会在 git 历史记录中看到 C。
git rebase --onto B' C
这转化为:获取自提交 C 以来我当前分支中的所有提交(在您的情况下,这只是 D) 并在 B'
之上播放
您还可以使用可选的 <branch>
参数同时执行检出和变基操作:
git rebase --onto B' C branch0
我 运行 在 PR 上使用 squash-merge 时遇到了类似的问题,当你有分支的分支时。
我的常见示例是如果我有一个功能分支 (feature-a
)。我将一些提交推送到那个分支。然后我创建另一个功能分支(feaure-b-off-a
)。然后我 squash-merge feature-a
进入 main,我会在 feature-b-off-a
的 PR 中看到重复提交到 main.
要解决此问题,我们可以使用 rebase --onto
,就像已接受的答案 。但手动工作是找到 C
(我指的是下面的 common-ancestor)。改写为另一种方式:
git rebase --onto main common-ancestor feature-b-off-a
- 获取
common-ancestor
和 feature-b-off-a
之间的所有提交并将它们变基到 main
幸运的是,git
有办法找到两个分支之间的 common ancestor:
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 的 PR 现在应该只显示新的提交。
奖金git-alias
注意:这假设您的流程是 squash-merging 都进入 main
git config --global alias.rebase-onto '!f() { git rebase --onto main $(git merge-base "" "") ""; }; 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
我有
A--B--C master
\
D branch0
然后我将 B
和 C
压缩成 B'
。
我如何变基 branch0
使其看起来像这样:
A--B' master
\
D branch0
我能想到的一个快速方法是,
git checkout branch0
记下 git log
git checkout master
现在将 branch0 重命名为 branch1
git branch -m branch0 branch1
A--B' master
\
D branch1
现在删除分支1
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
将 --onto
参数用于 git 变基,这会更改 git 重放工作的基线。
git checkout branch0
在此状态下,您应该仍会在 git 历史记录中看到 C。
git rebase --onto B' C
这转化为:获取自提交 C 以来我当前分支中的所有提交(在您的情况下,这只是 D) 并在 B'
之上播放您还可以使用可选的 <branch>
参数同时执行检出和变基操作:
git rebase --onto B' C branch0
我 运行 在 PR 上使用 squash-merge 时遇到了类似的问题,当你有分支的分支时。
我的常见示例是如果我有一个功能分支 (feature-a
)。我将一些提交推送到那个分支。然后我创建另一个功能分支(feaure-b-off-a
)。然后我 squash-merge feature-a
进入 main,我会在 feature-b-off-a
的 PR 中看到重复提交到 main.
要解决此问题,我们可以使用 rebase --onto
,就像已接受的答案 C
(我指的是下面的 common-ancestor)。改写为另一种方式:
git rebase --onto main common-ancestor feature-b-off-a
- 获取
common-ancestor
和feature-b-off-a
之间的所有提交并将它们变基到main
幸运的是,git
有办法找到两个分支之间的 common ancestor:
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 的 PR 现在应该只显示新的提交。
奖金git-alias
注意:这假设您的流程是 squash-merging 都进入 main
git config --global alias.rebase-onto '!f() { git rebase --onto main $(git merge-base "" "") ""; }; 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