Git:使用共享本地存储进行克隆(使用硬链接)

时间:2015-05-11 02:27:27

标签: git

我想让大量的开发人员轻松重复克隆一个非常大的远程git仓库。某种本地的每用户“缓存”是必要的。显然有很多方法可以做到这一点,我只是感到惊讶,似乎对我来说最自然的一种方式在git中不存在。

这是否有行业标准做法?
是否有一些我误解的git选项?

理想的解决方案

#first clone - very slow.
git clone ssh://remote.repo/repo.git repo1
#subsequent clones - lightning fast
git clone --shared-with-hard-links repo1 ssh://remote.repo/repo.git repo2

在这个虚构的解决方案中,没有创建.git/objects/info/alternates,对象只是使用硬链接在克隆上共享,比如rsync的--link-dest选项,或者当repo在本地文件系统上时,就像git的克隆一样。

我看到的替代品中,没有一个具有吸引力:

  1. 我可以做git clone --reference repo1 ssh://remote.repo/repo.git repo2依赖于repo1现有的,如果repo1被删除,那么repo2就会出现。
  2. 我可以git clone --dissociate --reference repo1 ssh://remote.repo/repo.git repo2但是存储空间没有共享,所以现在我已经用完了两倍的存储空间,而且由于这个原因,它可能仍然相对较慢。
  3. 各种复杂程度不同的黑客可能需要围绕克隆和拉动的包装。与真正的编程相比,复杂性显然是微不足道的,但是在一堆包装器下运行SCM只是一个真正应该避免的麻烦。
    • 将git'cache'repo存储在每个开发者PC的中央位置,并在克隆周围有一个包装器,首先自动获取缓存,然后clone --reference <cache>
    • 记住完成的每个克隆,后续克隆将查找预先存在的本地克隆并从中进行本地克隆(创建硬链接),然后在此之后修复遥控器。粗略地说,它是这样的:
  4. #find any existing clones... repo1
    git clone /path/to/repo1 repo2
    git remote rm origin
    git remote add origin ssh://remote.repo/repo.git
    git fetch
    #Abandon any local changes made in the other workspace
    for ref in $(git --git-dir "$gitdir" for-each-ref  refs/heads --format "%(refname)" ) ; do
        refbase=$(basename $ref)
        run_cmd git --git-dir "$gitdir" update-ref $ref remotes/origin $refbase
    done
    

    但这一切似乎都是黑客攻击。当然有更好的方法吗?

    谢谢,
    莫特

    注意:

    • 我们确实有一个LAN局部镜像。回购足够大,我们需要的不仅仅是为了达到合理的克隆速度。
    • 回购很重要。如果用户在Windows上,则需要11分钟克隆GigE,最多40分钟。

    更新

    我能做的最好的事情就是在/var/cache/git/<repo_name>.git中设置一个缓存,它是中心仓库的clone --mirror。新克隆使用--shared选项来减少初始克隆中的空间/时间并加速后续fetch es。有一个包装脚本clone一个新的工作区来执行此操作:

    git --git-dir /var/cache/git/<repo_name>.git remote update
    git clone --shared /var/cache/git/<repo_name>.git
    git remote set-url origin ssh://remote.repo/repo.git
    

    我更喜欢依赖硬链接的东西,因为如果以某种方式从共享缓存中删除对象,它们就不会受到问题的影响。但我想这不存在。

1 个答案:

答案 0 :(得分:3)

当您克隆本地存储库时,Git会默认执行硬链接。所以,你可以

git clone /path/to/repo /path/to/clone
cd /path/to/clone
git remote add upstream http://example.com/path/to/repo/to/clone
git fetch upstream

但这有许多缺点:

  • 下一个git gc将破坏硬链接并占用您的磁盘空间。
  • 仅当/path/to/repo/path/to/clone位于同一分区时才会有效。
  • 您必须小心使用结果上使用的工具,例如:没有rsync的{​​{1}}会复制所有硬链接。

    我认为-H在大多数情况下要好得多。