Git推送解析增量“已完成本地对象" [英] Git push resolving deltas "completed with local objects"

查看:96
本文介绍了Git推送解析增量“已完成本地对象"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

While I've been using git for a few years, my local git has recently been producing a new message (I'm presuming due to the growth of the repository).

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

When I do a git push to my remote on GitHub, I get the following output (quite natural, for the most part):

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和提交计数),所以我假设此消息与此有关,但是我不确定是否是这种情况.

The specific part I'm interested in is completed with n local objects, which has only started appearing recently. Since, for the most part, the repository is growing at a fairly good clip (both in LoC and commit count), I'm assuming that this message has something to do with that, but I'm not sure if that's the case.

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

I'm aware that this isn't an error (my git pushes have been working properly), but I'm merely curious as to the origin and meaning of this message, and why the number is so different from the actual number of objects being counted/calculated.

推荐答案

Bryan Pendleton's comment has the correct answer in it: your git push made a "thin pack". All fetch and push operations over smart protocols use thin packs all the time, to minimize network traffic.

任何打包文件都使用增量压缩.普通的Git包文件仅针对同一包中的其他对象进行增量压缩对象(这些其他对象也可以被增量压缩,但仅针对同一包中的更多对象). 精简包"是故意违反此规则的包文件:它针对存储在其他位置的其他(松散或打包)对象进行增量压缩对象.收到瘦包后,Git必须通过用丢失的对象填充"瘦包来固定"瘦包,或者干脆销毁它(将瘦包分解为未压缩的单个对象).

Any pack file uses delta compression. Normal Git pack files only delta-compress objects against other objects in the same pack (these other objects may also be delta-compressed, but only against yet more objects in the same pack). A "thin pack" is a pack file that deliberately violates this rule: it delta-compresses objects against other (loose or packed) objects stored elsewhere. Upon receiving a thin pack, a Git must "fix" the thin pack by "fattening it up" with the missing objects, or simply destroy it (exploding the thin pack into individual, not-delta-compressed, objects).

假设您的Git和其他一些Git正在协商发送一千兆字节的数据(但是在许多文件中,为简单起见,请说1),但是两个Git发现您已经拥有一千兆字节的文件数据,并且 new 数据可以表示为:复制旧数据,从中间删除字母a,然后插入the",或者类似的简短表示.无论执行什么Git发送操作,都会产生一个增量压缩的对象,说从具有哈希 h 的对象开始,在偏移量 x 处删除1个字节,在偏移量处添加3个字节the x ".要找出这个经过增量压缩的对象,需要花费大量的CPU时间(甚至可能需要整整一秒钟),但是只有几十个字节的空间.最终的打包文件很小,并且在几秒钟内就穿过了导线.接收方Git通过添加丢失的1GB对象来增强它,并且传输完成.

Suppose your Git and some other Git are negotiating to send a gigabyte of data (in however many files—let's just say 1 for simplicity), but the two Gits discover that you both already have a gigabyte of file data, and the new data can be represented as: "copy the old data, delete the letter a from the middle, and insert the instead", or something equally short and simple. Whichever Git is doing the sending makes a delta-compressed object saying "starting from object with hash h, delete 1 byte at offset x, add 3 bytes the at offset x". This delta-compressed object takes a lot of CPU time—maybe even a whole second—to figure out, but just a few dozens of bytes of space. The resulting pack file is tiny and goes across the wire in microseconds. The receiving Git fattens it up by adding the missing 1GB object, and the transfer is complete.

在这种情况下,completed with 12 local objects表示瘦包依赖于您的Git告诉您的Git您已经拥有的12个对象.由于Git的DAG,您的Git也许可以通过发送一个哈希ID来告知其Git您具有这些对象:如果您提交了 C ,则您拥有每棵树和提交 C 的Blob,并且-只要您没有浅"存储库,您就有每个祖先提交 C ,并且所有与祖先一起的树和Blob都会提交.

In this particular case, completed with 12 local objects means the thin pack relied on 12 objects your Git told their Git you already had. Because of Git's DAG, your Git may be able to tell their Git that you have these objects by sending just one hash ID: if you have commit C, you have every tree and blob that commit C has, and—as long as you don't have a "shallow" repository—you also have every ancestor to commit C, and every tree and blob that goes with those ancestor commits.

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

This kind of compression is thus a straightforward consequence of graph theory. It's also why, even for very large projects, the initial clone may be slow, but most git fetch updates tend to be quite fast. The main exception to this rule is when you give Git data objects that do not delta-compress well against previous data objects. This includes already-compressed binary files, such as JPG images or compressed tarballs. (Ironically, uncompressed tarballs could, in theory at least, compress much better, although Git's modified xdelta did not do a great job on them in a few cases I tested in the past.)

这篇关于Git推送解析增量“已完成本地对象"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆