基于多个分支的分支如何进行 git rebase?

3

我有以下极简示例:

---M---A-----D1---D2---D3
   |\       /|
   | B1---B2 |
   \         / 
    -C1---C2-

在这里,
M目前是主分支,有以下功能:
- A - B(包括B1、B2) - C(包括C1、C2)
此外还有一项由D1、D2、D3组成的功能D正在开发中。
现在,功能A已被接受并合并到主分支,因此我需要将所有内容变基到A。这意味着,我想要:
---M---A-----------D1'---D2'---D3'
       |\         /|
       | B1'---B2' |
       \           / 
        -C1'---C2'-

当然,将B(B2)与A进行合并以及单独合并C都很容易。

但是,如何在保留合并D1的情况下重新合并我的分支D(包括B和C)呢?

2个回答

2
您可以单独对分支B和C进行变基,然后使用嫁接(或git-replace)将新的变基分支重新附加到合并提交上。我会使用嫁接来完成此操作。
# rebase the individual branches
git rebase M B2 --onto A
git rebase M C2 --onto A
# replace old branch heads with rebased branch heads
echo $(git rev-parse D1) $(git rev-parse B2') $(git rev-parse C2') > .git/info/grafts

移动嫁接信息会使得你的Git历史记录看起来像D1有B2'和C2'作为父节点。如果你删除了.git/info/grafts文件,D1将恢复其原始父节点。

要使此更改永久生效,请使用filter-branch重写您的历史记录:

#make it permanent
git filter-branch -f --tag-name-filter cat D1'

更详细的解释可以在这个回答中找到,它讲述了如何将过去的提交添加到git仓库中,并解释了为什么应该使用git replace而不是grafts。我使用grafts给出了示例,因为我有更多相关经验。

相对于grafts,git replace 更适用于以下情况:

# rebase the individual branches
git rebase M B2 --onto A
git rebase M C2 --onto A
# replace old branch heads with rebased branch heads
git replace B2 B2'
git replace C2 C2'
#make it permanent
git filter-branch -f --tag-name-filter cat D1'

joshtkling的解决方案在简洁性方面远胜于这个。 - fraco

2

您需要在rebase命令中传递标志--preserve-merges。如下所示:

git checkout D
git rebase A --preserve-merges

我并不是 git 用于保留合并的算法专家,所以我不知道你可能会遇到什么样的冲突,但这将导致 git 在变基期间尝试重建你的合并提交 D1


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接