【问题标题】:How to git fetch efficiently from a shallow clone如何从浅克隆中有效地 git fetch
【发布时间】:2013-10-21 14:02:47
【问题描述】:

我们使用git to distribute an operating system and keep it upto date。我们无法分发完整的存储库,因为它太大(>2GB),所以我们一直在使用浅克隆(~300M)。但是recently when fetching from a shallow clone, it's now inefficiently fetches the entire >2GB repository。这是对部署带宽的一种站不住脚的浪费。

git 文档说您不能从浅存储库中获取,尽管这绝对不是真的。是否有任何解决方法可以使git clone --depth 1 能够获取它的变化?或者其他一些策略来保持分布大小尽可能小,同时让所有位 git 需要进行更新?

我尝试从--depth 20 克隆以查看它是否会更有效地升级,但没有成功。我也确实查看了http://git-scm.com/docs/git-bundle,但这似乎产生了巨大的捆绑。

【问题讨论】:

  • “但这似乎会产生巨大的捆绑”:仅适用于第一个。之后,您可以创建增量捆绑包。
  • 我的初始分布不可能很大...
  • 您将不得不再次尝试使用 Git 1.9/2.0(2014 年第一季度)获取您的浅层克隆:这些操作现在效率更高。见my answer below
  • Git 2.5(2015 年第二季度)支持单次提取提交!我在下面编辑了我的答案,现在引用“Pull a specific commit from a remote git repository”。

标签: git github shallow-clone


【解决方案1】:

--depth 是一个git fetch 选项。我看到文档并没有真正强调git clone 进行提取。

当您获取时,这两个存储库会交换有关谁拥有什么的信息,方法是从远程的头部开始并在获取的 refs 的历史中向后搜索最近的共享提交,然后填写所有丢失的对象以完成新的最近的共享提交和新获取的提交之间的提交。

--depth=1 fetch 只获取分支提示,没有先前的历史记录。这些历史的进一步获取将通过上述过程获取所有新的内容,但如果先前获取的提交不在新获取的历史中,则 fetch 将检索所有这些 - 除非您使用 --depth 限制获取。

您的客户从一个 repo 中提取了 depth=1 并将 URL 切换到了不同的 repo。在这个新的 repo 的 refs 中,至少有一个很长的祖先路径显然与你的 repo 中当前的任何东西都没有提交。这可能值得研究,但无论哪种方式,除非有某些特殊原因,您的客户都可以完成每次获取 --depth=1

【讨论】:

  • 正如您在我的test 中看到的,我很难重置为远程github.com/Webconverger/webc/commits/master 中的a26424。所以我不明白为什么它不能获取所有新的东西。如何比较远程参考? git ls-remote 只显示标签/分支...
  • 您切换了存储库。你在这个新的 repo 中有 10 个分支和 17 个标签,其中至少有一个引用了一个长期的祖先,与你的 repo 中的任何历史都没有共同的提交。
  • 所以.. IIUC,我应该修剪github.com/webconverger/webc(新仓库)上的分支/标签,以确保一切都与说“a26424”相同?
  • 或者只获取你想要的引用(要设置默认值,请参阅['remote..fetch](https://www.kernel.org/pub/software/scm/git/docs/git-fetch.html#_named_remote_in_configuration_file) entry in fetch`关于如何配置遥控器的讨论)
  • git fetch -v -v -v 顺便说一句,我发现它非常有用
【解决方案2】:

刚做了g clone github.com:torvalds/linux,花了很多时间,所以我就跳过了CTRL+C

然后g clone github.com:torvalds/linux --depth 1 确实克隆得非常快。我在git log 中只有一个提交。

所以clone --depth 1 应该可以工作。如果您需要更新现有存储库,您应该使用git fetch origin remoteBranch:localBranch --depth 1。它也有效,它只获取一个提交。

总结:

初始克隆:

git clone git_url --depth 1

代码更新

git fetch origin remoteBranch:localBranch --depth 1

【讨论】:

  • 我想将深度的东西添加到配置中,这样我就可以在不需要记住深度过滤器的情况下执行 git fetch origin。这可能吗?
  • 是的,您可能想要创建一个别名。这是 git 中别名的手册:git-scm.com/book/en/v2/Git-Basics-Git-Aliases
  • 只有 this 解决方案对我有用(--unshallow 不起作用)。密钥是branch:branch
【解决方案3】:

请注意,Git 1.9/2.0(2014 年第一季度)在获取浅层克隆时可能会更有效。
commit 82fba2b,来自Nguyễn Thái Ngọc Duy (pclouds)

现在 git 支持从浅层克隆或向浅层克隆传输数据,这些限制不再适用。

所有详细信息都在“shallow.c: the 8 steps to select new commits for .git/shallow”中。

您可以在0d7d285f2c681cc29a7b8 等支持中看到结果,它们支持克隆、发送包/接收包和/来自浅层克隆。
smart-http now supports shallow fetch/clone too
你可以even clone form a shallow repo

2015 年更新:git 2.5+(2015 年第二季度)甚至允许单次提交获取!见“Pull a specific commit from a remote git repository”。

2016 年更新(10 月):git 2.11+(2016 年第四季度)允许获取:

【讨论】:

    【解决方案4】:

    如果你可以选择一个特定的分支,它会更快。下面是一个使用 Spark master 分支和 latest 标签的例子:

    初始克隆

    git clone git@github.com:apache/spark.git --branch master --single-branch --depth 1
    

    更新到特定标签

    git fetch --depth 1 origin tags/v1.6.0
    

    以这种方式切换标签/分支变得非常快。

    【讨论】:

      【解决方案5】:

      我不知道它是否适合您的设置,但我使用的是在单独的目录中完整克隆一个 repo。然后我参考本地仓库从远程仓库进行浅层克隆。

      git clone --depth 1 --reference /path/to/local/clone git@some.com/group/repo.git 
      

      这样实际上只获取了与参考存储库和远程存储库的差异。为了更快,您可以使用--shared 选项,但请务必阅读git 文档中的限制(这可能很危险)。

      我还发现,在某些情况下,当遥控器发生很大变化时,克隆会开始获取太多数据。最好打破它并更新参考存储库(奇怪的是,它占用的带宽比一开始占用的要少得多。)然后再次启动克隆。

      【讨论】:

      • 我尝试了你的命令,无论有没有几个选项,我得到了像fatal: reference repository 'git@some.com/group/repo.git' is shallow这样的东西。
      • 您不能使用浅存储库/克隆作为参考。它必须是全深度克隆。
      • 你的意思是我不能用--depth 1
      • 不适用于参考存储库。
      猜你喜欢
      • 2017-04-25
      • 2020-06-26
      • 2011-06-23
      • 1970-01-01
      • 1970-01-01
      • 2018-04-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多