使用 Google 的 'repo' 工具进行多次签出的共享对象存储?

Shared object store for multiple checkouts with Google's 'repo' tool?

在我的组织中,我们使用 Google 的 repo 工具来维护分布在 ~200 git 个存储库中的代码库。由于编译和测试运行速度非常慢,我通常在我的 Linux 机器上检出该源代码树(例如,一个当前正在编译,另一个我准备下一次提交)。

这些签出的源代码树每个消耗大约 7.5GB,其中 5.5GB 是 git 对象存储(通常在每个存储库的 .git 文件夹中,但 repo 重定向这到源树根目录中的 .repo 文件夹),实际工作副本只有 2GB。所以我的问题是:我怎样才能(轻松地)让这些不同的结帐共享它们的对象存储,以便对象存储中的每个 git 对象在我的硬盘上只存储一次?

我知道这可以通过多次检出单个 git 存储库来实现,但我不确定存储库对对象存储的重定向可能会如何影响这些方法。简单地用硬链接替换重复文件可能行不通,因为 git 将大多数对象存储在共享包文件中,并且即使其中的对象是相同的,不同签出之间的对象也不相同。

我正在做的是:

  1. 运行 repo init 初始化新的 repo。

  2. .repo 中并创建两个名为 project-objectsprojects 的符号链接,它们指向现有 .repo 中的同名目录。

  3. 再上一层repo sync.

repo 到目前为止喜欢这个;如果我 运行 遇到任何问题,我会更新这个答案。

几乎可以肯定,我们希望避免在以这种方式共享对象的 repo 树中 运行 并发 repo 操作,因为这些操作反过来可以在同一个 git回购。

如果这是要走的路,下一步显然是将全局对象存储放在任何 .repo 目录之外的某个特殊位置,并通过符号链接将它们全部指向那里。

看起来 repo--mirror--reference 参数应该实现类似的功能,但我找不到任何关于它们的文档来解释它们到底做了什么 repo help init 不够详细。看起来好像 --mirror 应该拉下 repo 的本地镜像(不是客户端签出,而是一个特殊的镜像对象),然后在签出客户端 repos 时用 --reference 参数引用它。

符号链接的优点是我无需阅读未记录的 Python 源代码即可理解它们在做什么。

我做了一个原型:https://github.com/zhangchunlin/git-repo/commit/0c16efd203f0b768c103362386f9ae67730bb78f

但测试后效果不佳,当它很大时git需要打包成pack文件,repo的workspace 1和workspace 2会创建2个git pack文件,也就是说不共享。使用 git 1.9.1、2.10.1、2.18.0 进行测试,结果相同。

user1@server1:~/.project-objects/platform/external/sonivox.git/objects/pack$ ll
total 40648
drwxrwxr-x 2 user1 user1     4096  7月 11 22:30 ./
drwxrwxr-x 4 user1 user1     4096  7月 11 17:16 ../
-r--r--r-- 1 user1 user1   600272  7月 11 22:30 pack-1f3a4c983b7a4c0e6233201745b07f43e5c6daf4.idx
-r--r--r-- 1 user1 user1 20202460  7月 11 22:30 pack-1f3a4c983b7a4c0e6233201745b07f43e5c6daf4.pack
-r--r--r-- 1 user1 user1   600468  7月 11 17:16 pack-47b57752fd0d754b098b23654c31c8dc9be83cd0.idx
-r--r--r-- 1 user1 user1 20203424  7月 11 17:16 pack-47b57752fd0d754b098b23654c31c8dc9be83cd0.pack

如果能解决这个问题,我认为是可行的