【问题标题】:combining unrelated git repositories retaining history/branches合并不相关的 git 存储库,保留历史/分支
【发布时间】:2011-09-27 20:39:26
【问题描述】:

我们有 3 个独立的 git 存储库(每个都有一些分支),我们希望将它们合并为一个,以保持完整的历史记录和访问分支的能力,如下所示:

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

/A/.git
/B/.git
/C/.git

我们希望拥有一个包含 3 个子目录的超级仓库:

super/.git
super/A
super/B
super/C

并说当切换到分支 feature1(最初在 repo B 中,在 repo C 尚不存在时引入)时,我们希望结果是:

super/.git
super/A
super/B

我们已经阅读了Combining multiple git repositories,但是在使用 git-stitch-repo 时遇到了麻烦,它基本上可以像宣传的那样工作,只是超级仓库中缺少大量提交(没有任何错误消息会指出问题)。

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

编辑 我们知道子模块和子树合并,但两者都不是一个选项。这应该是一次性操作。我们需要回购永远加入。

编辑 可能是提出基本相同问题的一种更简单的方法:假设我们有一个带有 3 个完全不相关的分支的仓库。我们可以将它们合并到一个分支而不会发生冲突(因为它们不共享文件)。现在,在查看历史时,我们会看到 3 个不相关的提交分支以及它们聚集在一起的一个点。但我们希望看到的是由所有 3 个分支的交错(按日期/时间)提交组成的一个分支。

【问题讨论】:

  • 您是否尝试过该问题中建议的任何其他方法(组合多个 git 存储库)?那里有几个选项。
  • 是的,我们做到了。他们似乎都没有做 git-stitch-repo 所做的事情,它真正按时交错提交,因此生成的 repo 完全感觉好像它从一开始就包含了所有部分。只是,如前所述,git-stitch-repo 会随机将文件排除在外..
  • 好的,然后从每个分支的git log --format=%d%H 创建一个文件。将其通过 sort 然后传递到 xargs 并在新分支上 git cherry-pick 。你可能想先用 rebase 来展平历史。
  • 鉴于您的最后评论,我添加了一个指向我编写的可以执行此操作的工具的链接;在处理大量分支并逐步执行此操作时,简单地重新设置和排序对我来说还不够

标签: git


【解决方案1】:

你不想要子模块,因为你会用你将发出的所有 git submodule update 命令拉你的头发。您还必须发出 3 个 git log 命令而不是一个,才能查看在一定时间内发生了什么。

将所有历史记录整合到一个存储库中。使用 filter-branch 重置每个 repos 历史所在的目录。无需缝合。执行过滤器分支后,您可以随时简单地合并。

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

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

调整剪切,使其只需要散列。没有尝试过,但让我知道它是如何工作的。您可能需要先使用 rebase 来展平历史。您不能从 3 个不同的历史中交错不同的分支和合并。

希望这会有所帮助。

【讨论】:

  • 嗯,有点……如果我们这样做,我们最终会得到 3 棵不相关的树,它们在当前点合并为一棵。现在,当签出属于以前的存储库之一的较早版本时,我们只获取此存储库的文件。如上所述,我们希望在该修订时已经存在的其他文件(即使是其他原始存储库)也存在。和 git-stitch-repo 做我们想要的,但显然是错误的,因为在缝合后丢失了一些随机文件/提交..
  • 感谢第二个选项,但我不得不说我们没有尝试过。我们已经在这方面花费了太多时间,而且听起来不太乐观。我们最终对不相关的分支进行了简单的合并,这意味着当我们回到过去时,我们只会看到一个分支。
  • 这是可能的,但由于必要的扁平化以使它们正确交织,您可能会丢弃有用的历史信息。祝你一切顺利。
【解决方案2】:

splice_repos 是我编写的一个工具,它将来自不同存储库的提交交错到一个新的存储库中,以便同名分支获得合并的历史记录(就好像它们按历史顺序提交一样),而不仅仅是在以不同分支上的不同历史结束。后面有一个blog entry describing the rationale

【讨论】:

【解决方案3】:

可能最简单的方法是使用submodules。它并不能完全说明您想要实现的情况,但它非常接近并且不太容易让人头疼。

只需创建一个新目录并将其 git init 作为您的“超级”存储库。然后使用上面链接中给出的命令添加您的 A、B 和 C 存储库。

【讨论】:

  • 谢谢,我们知道子模块,但它们不是一个选项。我将该信息添加到我原来的问题中。
猜你喜欢
  • 1970-01-01
  • 2014-12-17
  • 1970-01-01
  • 2015-04-17
  • 2016-04-18
  • 2017-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多