使用 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 将大多数对象存储在共享包文件中,并且即使其中的对象是相同的,不同签出之间的对象也不相同。
我正在做的是:
运行 repo init
初始化新的 repo。
在 .repo
中并创建两个名为 project-objects
和 projects
的符号链接,它们指向现有 .repo
中的同名目录。
再上一层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
如果能解决这个问题,我认为是可行的
在我的组织中,我们使用 Google 的 repo
工具来维护分布在 ~200 git 个存储库中的代码库。由于编译和测试运行速度非常慢,我通常在我的 Linux 机器上检出该源代码树(例如,一个当前正在编译,另一个我准备下一次提交)。
这些签出的源代码树每个消耗大约 7.5GB,其中 5.5GB 是 git 对象存储(通常在每个存储库的 .git
文件夹中,但 repo
重定向这到源树根目录中的 .repo
文件夹),实际工作副本只有 2GB。所以我的问题是:我怎样才能(轻松地)让这些不同的结帐共享它们的对象存储,以便对象存储中的每个 git 对象在我的硬盘上只存储一次?
我知道这可以通过多次检出单个 git 存储库来实现,但我不确定存储库对对象存储的重定向可能会如何影响这些方法。简单地用硬链接替换重复文件可能行不通,因为 git 将大多数对象存储在共享包文件中,并且即使其中的对象是相同的,不同签出之间的对象也不相同。
我正在做的是:
运行
repo init
初始化新的 repo。在
.repo
中并创建两个名为project-objects
和projects
的符号链接,它们指向现有.repo
中的同名目录。再上一层
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
如果能解决这个问题,我认为是可行的