如何在git中安全地使用共享对象数据库?

Mar*_*air 24 git

我已经在几个地方读过,可以objects在多个git存储库之间共享目录,例如使用符号链接.我想这样做在同一目录中的几个裸存储库之间共享对象数据库:

shared-objects-database/
foo.git/
  objects -> ../shared-objects-database
bar.git/
  objects -> ../shared-objects-database
baz.git/
  objects -> ../shared-objects-database
Run Code Online (Sandbox Code Playgroud)

(我这样做是因为在每个对象目录中会有大量冗余存储的大blob.)

我对此的关注是,在使用这些存储库时,git gc将自动调用并导致从一个存储库无法访问的对象被修剪,从而使其他存储库不完整.有没有简单的方法可以确保不会发生这种情况?例如,是否存在一个强制--no-prune为默认值的配置选项git gc,如果是这样,是否足以使用此设置而不会有丢失数据的风险?

目前,我一直在使用这种objects/info/alternates机制在这些存储库之间共享对象,但是将这些指针从每个存储库维护到所有其他存储库都有点笨拙.

(我的另一种方法是只具有单一的裸库,与各分支机构foo.git,bar.gitbaz.git命名为foo-master,foo-testing,bar-master,等.然而,这会是一个有点更多的工作来管理,因此,如果符号链接的对象目录可以安全地工作,我宁愿那样做.)

您可能会猜到这是使用Git For It It It Not It用例的其中一个,但我希望这个问题清晰有效;)

Chr*_*man 10

在问到/回答这个问题之后,也许这被添加到git中:现在似乎有一种方法可以明确地做到这一点.它在这里描述:

https://git.wiki.kernel.org/index.php/Git_FAQ#How_to_share_objects_between_existing_repositories.3F

如何在现有存储库之间共享对象?做

echo "/source/git/project/.git/objects/" > .git/objects/info/alternates
Run Code Online (Sandbox Code Playgroud)

然后跟进

git repack -a -d -l
Run Code Online (Sandbox Code Playgroud)

-l意味着它只会在包文件中放入"本地"对象(严格来说,它也会从备用树中放置任何松散的对象,所以你将拥有一个完全打包的存档,但它不会已经在备用树中打包的重复对象).

  • 我很想拒绝这个仅限链接的答案.但后来我想"嗯,让我们编辑它" (3认同)
  • 问题说这是他们已经在使用的技术。在某些情况下这是一个很好的解决方案,但对于其他情况来说这是有问题的。这种方法创建了一种单向共享,因此一旦您开始通过各个存储库获取数据,它们就会积累自己的重复对象。它并没有真正实现消除重复的目标,除非您_仅_从中央对象存储库中获取 (2认同)

Cas*_*bel 9

为什么不把gc.pruneExpire变量调到最近never?您不可能拥有1000年前不想删除的松散物体.

为了确保真正应该修剪的东西得到修剪,你可以保留一个包含所有其他作为遥控器的回购.git gc因为它确实知道什么是无法到达的,所以在那个方面会非常安全.

编辑:好的,我对时间限制有点骑士; 正如评论中指出的那样,1000年不会太好用,但是这个时代的开始会,或者never.

  • Jefromi:也许你可以用一些注释来更新你的答案?我不是 100% 确定这一点,但是在 git.git 中进行测试,我怀疑超过 39 年的值可能不起作用,因为它们可以追溯到纪元开始之前。但是,由于此提交:http://github.com/git/git/commit/cbf731ed4ec511f2c32598e03d7865f35881fea2,您可以将 gc.pruneExpire 设置为“never”,这将起作用。(从“git tag --contains cbf731ed4ec511f2”看来,v1.7.0.3 之后(并包括)的版本应该没问题。) (2认同)