结合不相关的git存储库保留历史/分支


combining unrelated git repositories retaining history/branches

我们有3个独立的Git存储库(每个都有一些分支),我们希望将它们组合成一个完整的历史记录和访问分支的能力,如:

这就是我们所拥有的。3回购:

1
2
3
/A/.git
/B/.git
/C/.git

我们想要一个有三个子目录的超级回购:

1
2
3
4
super/.git
super/A
super/B
super/C

当切换到分支功能1(最初在回购B中,在回购C还不存在的时候引入)时,我们希望结果是:

1
2
3
super/.git
super/A
super/B

我们已经阅读过组合多个Git存储库的文章,但是使用Git Stitch Repo时遇到了一些问题,因为它基本上只能像广告中所说的那样工作,因为在超级repo中丢失了大量提交(没有任何指向问题的错误消息)。

知道我们在这里可能做错什么吗?

编辑我们知道子模块和子树合并,但这两者都不是一个选项。这应该是一次性操作。我们需要将回购协议永久地结合在一起。

编辑可能是一个简单的方法来回答基本相同的问题:假设我们有一个回购,有3个完全不相关的分支。我们可以将它们合并到一个分支(因为它们不共享文件)。现在,当我们回顾历史时,我们看到了3个不相关的承诺分支,以及它们聚在一起的一点。但我们希望看到的是一个分支,由所有3个分支的交错提交(按日期/时间)组成。


Splice eu repos是我写的一个工具,它将来自不同存储库的提交交错到一个新的存储库中,这样相同的命名分支就可以合并历史(就像它们是按历史顺序提交的一样),而不仅仅是在最后将它们与不同分支上的单独历史合并在一起。有一篇博文描述了它背后的原理。


你不需要子模块,因为你会用你将要发出的所有git子模块更新命令把头发拔出来。您还必须发出3个git-log命令而不是一个来查看在一定时间内发生了什么。

把所有的历史记录放在一个报告中。使用filter branch重置每个repos历史记录所在的目录。不用缝针。完成过滤器分支后,您可以在任意点进行合并。

基本上,repoa/master、repob/master和repoc/master将存在于您创建的新repo中(尽管您可以从其中一个开始)。应用过滤器分支之后,每个提交中的每一棵树都将有一个新的根节点,它将是一个目录(A代表repoa分支,B代表repob分支,等等)。

1
2
git checkout -b newbranch --root
git log --all --format=%ad%H | sort | cut -c10- | xargs -n 1 git cherry-pick

调整切割,使它只接受散列。还没试过,但告诉我它是怎么工作的。您可能需要先用REBASE将历史展平。你不能交错不同的分支,合并3个不同的历史。

希望这有帮助。


可能最简单的方法是使用子模块。它并不完全符合你想要达到的目标,但它非常接近,不容易头痛。

只需创建一个新目录并将其初始化为"super"repo。然后使用上面链接上给出的命令添加A、B和C repos。