如何将几个Git仓库合并为一个并交织历史

m-b*_*tes 5 git git-rewrite-history

我的情况是我有两个Git存储库,我需要将它们合并到一个存储库中(实际上有更多的存储库,但是我可以从两个开始)。

这两个存储库是:

  • 主存储库,
  • 所述第二存储库,

在库中的代码对在库中的代码依赖性(但反之亦然),和两个库的历史彼此跟随以时间的方式-大致(即一个特定的在回购提交通常需要从回购提交一个具有非常相似的提交时间)。

两个存储库中的分支名称和标记名称冲突(不能保证它们都属于同一名称),但是仅需要保留A中的引用。

新存储库C的要求是:

  1. 所有的裁判(分支和标签)一个需要被保留。
  2. 仅需要保留来自B的master分支提交(即,由报告的提交git log --first-parent master)。
  3. 每个源存储库中的文件应放入新存储库的子文件夹中(即,A中的文件应放入A/B格式的文件应放入B/)。
  4. 当检查出具体的承诺(包括完成提交合并)在库Ç(例如某个发布标签)兼容的文件形成两个源库应在目录中找到A/B/(至少在提交或两个)。

到目前为止,我已经尝试了几种方法,包括thisgit-stitch-repo,但是没有成功(它们没有满足上述要求)。

在这一点上,我已经设法:

  • 使用git filter-branch将每个仓库中的所有文件移动到一个子目录。例如回购A
mkdir A
mv * .gitignore A / 2> / dev / null
git commit -a -m'DROPME'> / dev / null
git filter-branch --tag-name-filter cat --index-filter'git ls-files -s | sed“ s- \ t \” *-&A /-“ | GIT_INDEX_FILE = $ GIT_INDEX_FILE.new git update-index --index-info && mv” $ GIT_INDEX_FILE.new“” $ GIT_INDEX_FILE“ ||:'--所有
git reset-硬来源/主
git for-each-ref --format =“%(refname)” refs / original / | xargs -n 1 git update-ref -d
  • 使用git fast-export / fast-import将 repo B导入到A中
  • 提供一种用于生成映射的方法,以便对于A中的给定SHA ,存在应从B插入的零,一个或多个SHA:列表。

我现在所期待的,无非是一些聪明的使用git的过滤分支应该使我能够从选定提交插入到的主分支一个。但是如何?

m-b*_*tes 5

事实证明,该解决方案比我期望的要复杂得多。它涉及操纵和组合两个(或多个)git fast-export流的输出,并使用将它们导入到新的存储库中git fast-import

简而言之,fast-import通过遍历两个输入流并根据来自主分支的按日期排序的日志在它们之间来回切换来生成新的流。

我已经实现在一个名为Python脚本的解决方案join-git-repos.py,我把在GitHub的仓库在这里