git clone --shared和--reference有什么区别?

时间:2014-04-25 22:51:42

标签: git

阅读完文档后,我仍然不明白这是什么 差异介于--shared--reference <repo>之间。它们看起来很相似。

  1. --shared 之间有何区别? --reference <repo> 选项?

  2. 可以在制作多个本地克隆时使用它们来节省驱动器空间 另一个本地克隆?

  3. 每个本地克隆都可以签出不同的分支吗?

  4. 注意:我知道我可以使用多个带有截断的浅克隆 历史记录使用git clone --depth <depth>,但每个克隆仍然必须 为了做到这一点,重复 至少一些 历史,所以我是 认为它可能不是节省驱动器空间的最佳方式(尽管它 总比没有好。)

    背景

    有时候,我希望在一个帐户中有一个以上的工作副本结帐 存储库,所以我创建了多个克隆,其中每个克隆都有自己的结帐。

    然而,我并不是真正需要每个克隆的整个历史,只是最多 我的分支机构的最新版本,所以我可以节省很多驱动器 通过让每个克隆使用标记,提交,树和blob对象来实现空间 原始的本地克隆(例如,通过符号链接)。

    git clone文档

    我查看了the git clone documentation以查看是否有我的任何内容 可以使用。

    --shared

    我看到那里有一个--shared选项:

      

    当要克隆的存储库位于本地计算机上时,而不是使用硬盘   链接,自动设置.git/objects/info/alternates以共享对象   与源存储库。生成的存储库没有任何启动   它自己的对象。

    这似乎 可能 对于帮助我节省驱动器空间非常有用 具有不同签出的多个克隆,因为每个克隆共享 具有原始本地克隆的对象。

    --reference <repository>

    然后我也看到了--reference <repository>选项:

      

    如果参考存储库位于本地计算机上,则自动设置   .git/objects/info/alternates从引用中获取对象   库。使用现有的存储库作为替代将需要   从要克隆的存储库中复制的对象越来越少,从而减少了网络   和本地存储成本。

         

    注意:请参阅--shared选项的注意事项。

    这表示它会降低本地存储成本,因此这可能很有用 好。

3 个答案:

答案 0 :(得分:10)

两个选项都更新.git/objects/info/alternates以指向源存储库,这可能很危险,因此文档中的两个选项都会出现警告说明。

--shared选项不会将对象复制到克隆中。这是主要的区别。

--reference使用其他存储库参数。在克隆过程中,使用--reference仍然会将对象复制到目标中,但是当指定对象在参考存储库中已经可用时,可以从现有源复制这些对象。这可以通过使用--reference

将路径传递到更快/本地设备上的存储库来减少源存储库中的网络时间和IO

亲自看看

创建--shared克隆和--reference克隆。使用git count-objects -v计算每个对象。您会注意到共享克隆没有对象,并且引用克隆具有与源相同数量的对象。此外,请注意文件系统中每个的大小差异。如果您要移动源,并在共享和参考存储库中测试git log,则日志在共享克隆中不可用,但在引用克隆中工作正常。

答案 1 :(得分:5)

link in the comments to your question确实是一个更清晰的答案:--reference隐含--shared --reference的目的是在远程存储库的初始克隆期间优化网络I / O.

与上面的答案相反,我发现来自同一来源的--shared--reference存储库具有相同的大小,并且都具有零对象。当然,如果您将--reference用于基于公共源的其他存储库,则大小和对象将反映存储库之间的差异。 注意,在这两种情况下,我们都没有在工作树中节省空间,只有.git/objects

维持此设置有一些细微差别 - 请阅读主题以获取更多详细信息。从本质上讲,这两个应该被视为公共存储库,在重新打包/修剪/垃圾收集的情况下重视历史重写。

在初始克隆之后保持最佳磁盘空间使用率的工作流程似乎是:

  1. 拉源
  2. 重新包装来源
  3. 拉二级
  4. 次要
  5. git gc
  6. 可能最好阅读该主题中的讨论。

    您可以将源objects目录的绝对路径放入secondary/.git/objects/info/alternates并运行git gc(许多人使用{{1} },由git repack -a -d -l完成。

    您可以通过在辅助设备中运行git gc(无git repack -a -d)删除备用设备,然后从-l文件中删除该行。如线程中所述,可以有多个备用。

    我自己并没有那么多使用,所以我不知道管理它是多么容易出错。

答案 2 :(得分:2)

您问题的link in the comments现在已消失。

https://www.oreilly.com/library/view/git-pocket-guide/9781449327507/ch06.html关于此主题的一些重要信息。这里是其中的一些内容:

首先,我们对远程存储库进行裸克隆,以进行共享 在本地作为参考存储库(因此称为“ refrep”):
$ git clone --bare http://foo/bar.git refrep

然后,我们再次克隆遥控器,但这一次将refrep作为 参考:
$ git clone-参考refrep http://foo/bar.git

此选项与--shared选项之间的主要区别在于 仍在跟踪远程存储库,而不是refrep克隆。什么时候 拉动,您仍然与http://foo/联系,但是您无需等待 它发送任何已经在本地存储在refrep中的对象; 当您推送时,您正在更新foo的分支和其他引用 直接存储库。

当然,只要您和其他人开始推送新的提交, 参考资料库将过时,您将开始迷失方向 一些好处。您可以定期运行git fetch --all refrep引入任何新对象。单个参考资料库可以 成为许多其他对象的缓存;只需将它们添加为 参考中的遥控器:

$ git remote add zeus http://olympus/zeus.git
$ git fetch --all zeus