假设我们有以下修订图:
A-X-Z--B
\
\-C
A在B和C之前。进一步假设我从上游重新绑定A,创建一个新的提交A *,然后将B和C重新绑定到A *上。生成的修订图如下:
A*-X'-Z'-B
\
\-X"-Z"-C
请注意,不再共享共享历史记录。有没有一种简单的方法可以解决这个问题,除了说,重新定义B然后明确地将C重新定位到Z'。换句话说,是否有更好的方法可以同时自动修改多个分支以保留共享历史记录?在分割点上人工放置标记或者手动检查图形以找出修改C的提交的sha1以保持共享历史记录似乎有点尴尬,更不用说开放可能性了错误,特别是因为我必须在每次改变时都这样做,直到我检查上游分支的变化。
答案 0 :(得分:16)
git rebase --committer-date-is-author-date --preserve-merges --onto A* A C
git rebase --committer-date-is-author-date --preserve-merges --onto A* A B
这应该保持公共提交具有相同的sha1并保留任何合并。在这种情况下,不需要保留合并,但是这将成为一个不太重要的历史问题。
要为历史记录中包含A的所有分支执行此操作:
git branch --contains A | xargs -n 1 git rebase --committer-date-is-author-date --preserve-merges --onto A* A
希望这有帮助。
更新:
这可能是更清晰的语法:
for branch in $(git branch --contains A); do git rebase --committer-date-is-author-date --preserve-merges --onto A* A $branch; done
答案 1 :(得分:2)
我关注的是一个类似的问题:重新定义一个完整的子历史 - 几个分支,它们之间由于合并而产生一些联系:
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
(移动分支参考和标签也许可以with a script完成。)
如果topicC
未合并到topicB
,我可以创建一个虚假的顶级提交来合并我想要重新绑定的所有分支,例如:
git checkout -b fake topicB
git merge -s ours topicC
然后以这种方式改变它:
git rebase -p A fake --onto A*
并将主题分支重置为新提交,删除假分支。
我相信带--committer-date-is-author-date
的{{3}}也是好的和明智的,但根据我与Git的经验,我没有这个想法并且解决了在共享历史之后保持共享历史的问题。改变我在这里的补充答案中描述的方式。