【问题标题】:Git push resolving deltas "completed with local objects"Git推送解决增量“用本地对象完成”
【发布时间】:2016-12-24 16:29:42
【问题描述】:

虽然我已经使用 git 几年了,但我本地的 git 最近一直在生成一条新消息(我推测是由于存储库的增长)。

当我在 GitHub 上对我的遥控器执行 git push 时,我得到以下输出(大部分情况下很自然):

Counting objects: 99, done
Delta compression using up to 4 threads.
Compressing objects: 100% (97/97), done.
Writing objects: 100% (99/99), 10.16 KiB | 0 bytes/s, done.
Total 99 (delta 66), reused 0 (delta 0)
remote: Resolving deltas: 100% (66/66), completed with 12 local objects

我感兴趣的具体部分是completed with n local objects,它最近才开始出现。由于在大多数情况下,存储库的增长速度相当不错(在 LoC 和提交计数方面),我假设此消息与此有关,但我不确定是否是这种情况。

我知道这不是错误(我的 git pushes 一直在正常工作),但我只是好奇这条消息的来源和含义,以及为什么这个数字与正在计数/计算的对象的实际数量。

【问题讨论】:

  • 这可能是 git 告诉你它使用“瘦包”来执行推送的方式。我认为如果 git 有理由认为优化网络带宽会是一个胜利,它通常会选择这个。

标签: git github


【解决方案1】:

Bryan Pendleton's comment 里面有正确的答案:你的git push 做了一个“瘦包”。所有基于智能协议的获取和推送操作始终使用精简包,以最大限度地减少网络流量。

任何包文件都使用delta compression。普通 Git 包文件仅针对同一包中的其他对象进行增量压缩对象(这些其他对象也可能进行增量压缩,但仅针对同一包中的更多对象)。 “瘦包”是故意违反此规则的包文件:它将对象与存储在其他地方的其他(松散或打包)对象进行增量压缩。收到瘦包后,Git 必须通过用丢失的对象“增肥”来“修复”瘦包,或者干脆将其销毁(将瘦包分解为单独的、非 delta 压缩的对象)。

假设您的 Git 和其他一些 Git 正在协商发送 1 GB 的数据(无论在多少文件中,为了简单起见,我们只说 1),但是这两个 Git 发现你们都已经有了 1 GB 的文件数据,并且数据可以表示为:“复制旧数据,从中间删除字母a,并插入the”,或者同样简短而简单的内容。无论哪个 Git 正在发送,都会生成一个 delta 压缩对象,说“从具有散列 h 的对象开始,在偏移量 x 处删除 1 个字节,在偏移量处添加 3 个字节 the x”。这个 delta 压缩的对象需要大量的 CPU 时间——甚至可能一秒钟——来计算,但只需要几十个字节的空间。生成的包文件很小,可以在几微秒内通过网络。接收端的 Git 通过添加缺失的 1GB 对象使其变胖,传输完成。

在这种特殊情况下,completed with 12 local objects 表示瘦包依赖于您的 Git 告诉他们的 Git 您已经拥有的 12 个对象。由于 Git 的 DAG,你的 Git 可以通过发送 一个 哈希 ID 告诉他们的 Git 你有这些对象:如果你有提交 C,你就有了每一棵树和提交 C 具有的 blob,并且——只要你没有“浅”存储库——你有每个祖先提交 C em>,以及与这些祖先提交相关的每棵树和 blob。

因此,这种压缩是图论的直接结果。这也是为什么即使对于非常大的项目,初始克隆可能会很慢,但大多数git fetch 更新往往相当快。这条规则的主要例外是当你提供的 Git 数据对象不能很好地与以前的数据对象进行增量压缩时。这包括已压缩的二进制文件,例如 JPG 图像或压缩的 tarball。 (具有讽刺意味的是,un压缩的 tarball 至少在理论上可以压缩得更好,尽管 Git 修改后的 xdelta 在我过去测试的一些案例中并没有很好地处理它们。)

【讨论】:

  • 感谢您的回答,有道理!这是最近在 Git 中的吗?
  • @sardaukar:消息是新的。不过,“瘦包”的概念或多或少地一直存在于 Git 中。
【解决方案2】:

注意:消息本身(completed with %d local objects)不是新的,是在commit a984a06, Nov. 2007, Git v1.5.4-rc0中引入的

更好地显示瘦包完成

本着为普通人美化 Git 输出显示的相同精神,这里有一个简单的进度 API 扩展,允许在终止进度线时提供最终消息,并使用它来显示所需的对象数量完成一个轻薄的包装,再节省一行屏幕显示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-28
    • 2013-06-10
    • 2014-06-06
    • 1970-01-01
    • 2012-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多