假设我们有以下修订图:
A-B (master)
\
C (feature-a)
\
D (feature-b) [depends on feature a]
\
E (feature-c) [depends on feature b]
然后修改master以跟随commit F
。 是否有任何简单的方法可以将E
重新定位到F
(主要),以便分支feature-a
,feature-b
和feature-c
最终如下:
A-B-F (master)
\
C' (feature-a)
\
D' (feature-b)
\
E' (feature-c)
在现实世界中,每个功能之间显然存在多个补丁,因此在手动重新连接分支到重新定位的历史记录是繁琐且容易出错的工作。我知道我可以使用简单的E
将E'
重新定义为git checkout feature-c && git rebase master
,但会使分支feature-a
和feature-b
指向提交C
和{ {1}}代替D
和C'
。 Rebase应该拥有移动所有分支的所有信息,对吗?
答案 0 :(得分:2)
git没有内置任何功能,但它确实可以编写脚本。
您需要做的是:
feature-a
,feature-b
和feature-c
)。X
是Y
的前身,如果Y
是X
的后代(并选择此处处理/断开关系 - 两个分支名称标识同一承诺)。在这种情况下,feature-a
是feature-b
和feature-c
的前身,而feature-b
是feature-c
的前身(仅限)。保存前辈的“距离返回”值(追逐父链的距离)。feature-c
):
(就是这样,一切都完成了。)
使用git merge-base --is-ancestor
(成对)或git branch --contains
进行前置测试很容易(一次性,但需要过滤掉非重新分支的分支)。找到“N back”值有点棘手,但我相信可以通过git rev-list
传送到wc -l
来完成。
编辑:我看到链接的答案(在上面的评论中)使用了类似的算法 - 包括拓扑排序/周期性检查,因为分支选择方法不是“从提交DAG中获取” - 但需要更多工作,根据指示明确重新定位每个分支。如果你在DAG工作,那么leaf rebase已经完成了所有的工作,并且可以简单地重新标记前辈,正如我所指出的那样。
答案 1 :(得分:1)
试试这个:
git checkout featurea
git rebase
git branch --contains (sha1 of your old commit C) |xargs -n 1 git rebase --onto (sha1 of your new commit C') (sha1 of your old commit C)
答案 2 :(得分:0)
我目前能想到的最好的方法是一个接一个地改变:
git rebase --onto master B feature-a
git rebase --onto feature-a C feature-b
git rebase --onto feature-b D feature-c
但是无论何时遇到这样的问题,请再想一想,如果你真的想要这样,并了解后果。
答案 3 :(得分:0)
应该很简单。在E
上重新F
会使整个分支机构提交C
和D
。
git checkout B
…
git commit -m 'F'
git checkout E
git rebase F