git rebase一个基于几个分支的分支

时间:2014-03-10 17:16:21

标签: git rebase

我有以下最小例子:

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

下面,

  • M现在是主人,
  • 有特色
    • A,
    • B(由B1,B2组成)和
    • C(由C1,C2组成)

正在开发中并且在所有这些功能之上

  • D(由D1,D2,D3系列组成)。

现在功能A被接受进入主分支,因此我必须将所有内容重新设置为A.这意味着,我想要

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

当然,很容易在A处单独使用B(B2),也可以单独/单独地在C处单独使用。

但是如何修改我的分支D(包括B和C),保持合并D1(如上所示)?

2 个答案:

答案 0 :(得分:2)

您需要将标记--preserve-merges传递给rebase命令。这看起来像:

git checkout D
git rebase A --preserve-merges

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

答案 1 :(得分:2)

您可以单独重新分支B和C分支,然后使用grafts(或git-replace)将新的rebased分支重新附加到合并提交。使用移植物我会做

# 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将再次拥有原始父母。

要使此永久化,请使用过滤器分支重写历史记录:

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

可以在this answer on prepending the past to a git repository中找到更详细的解释。它还解释了如何使用git替换而不是移植物。我用移植物给出了这个例子,因为我对这些有了更多的经验。

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'