一般情况下的问题
我担心一个类似的问题:重新定位整个子历史——几个分支,它们之间的一些链接是由合并产生的:
A--B-B2-B3 <--topicB
\ /
\-C-C2-C3 <--topicC
如果我顺序运行几个git rebase
(对于 topicB 和 topicC),那么我怀疑分支之间的合并是否可以正确保留。所以我需要一次重新调整所有分支,希望能正确重建它们之间的合并。
在特定子案例中工作的“解决方案”
就我而言,我很幸运,topicC
它实际上被合并到了topicB
:
A-B-----------B2-B3 <--topicB
\ /
\-C-C2-C3 <--topicC
所以要重新定义整个子历史,我可以运行
git rebase -p A topicB --onto A*
(A*
新的基础在哪里,而不是A
,如您的问题中的那样;topicB
是最初指向旧提交 B3 和B3'
之后重写的提交的分支名称;-p
是选项的简称--preserve-merges
),获得如下历史记录:
A-B-----------B2-B3
\ /
\-C-C2-C3 <--topicC
A*-B'-------------B2'-B3' <--topicB
\ /
\-C'-C2'-C3'
然后将所有剩余的分支引用(和标签)重置为新的相应提交(在新的子历史中),例如
git branch -f topicC C3'
有效:
A*-B'-------------B2'-B3' <--topicB
\ /
\-C'-C2'-C3' <--topicC
(移动分支引用和标签也许可以通过脚本来完成。)
受特定案例启发的一般案例的“解决方案”
如果topicC
没有合并到topicB
,我可以创建一个假的顶级提交来合并我想要重新设置的所有分支,例如:
git checkout -b fake topicB
git merge -s ours topicC
然后以这种方式重新设置它:
git rebase -p A fake --onto A*
并将主题分支重置为新提交,删除假分支。
其他答案
我相信另一个答案也是好的--committer-date-is-author-date
和明智的,但是根据我使用 Git 的经验,我没有这个想法并解决了在我在附加答案中描述的方式重新设置基础后保持共享历史真正共享的问题这里。