git二进制差异algorithm(增量存储)是标准化的吗?

Git使用增量压缩来存储彼此相似的对象。

这个algorithm是否被标准化,并在其他工具中使用? 是否有描述格式的文档? 它是否与xdelta / VCDIFF / RFC 3284兼容?

我认为用于包文件的差异化algorithm与其中一个delta编码链接: 最初(2005)xdelta ,然后是libXDiff 。
但是,如下所述,它转向了一个自定义的实现。

无论如何,正如这里所提到的 :

Git 在包装文件中进行分离。
但是当你通过SSH推动git会产生一个包含提交对方没有的包文件,这些包是薄包,所以他们也有增量…但远程端然后添加基地,这些薄包使他们独立。

(注意:创build很多包文件,或者在庞大的文件包中检索信息代价高昂 ,并解释为什么git不能处理好大文件或大回购。
查看更多在“ 与大文件的Git ”)

这个线程还提醒我们:

实际上, 由于networking带宽 (比磁盘空间成本更高)以及使用单个mmapped文件而不是非常大的数字的I / O性能 ,我记忆和理解的实际上是packfiles和deltification( LibXDiff,而不是xdelta )松散的物体。

在2008年的线程中提到了LibXDiff。

然而,从那时起,algorithm就已经发展了,可能是自定义的,正如2011年的线程所说明的那样 ,而diff-delta.c的头文件指出:

所以,严格来说,Git中的当前代码与libxdiff代码根本没有任何相似之处。
但是两个实现背后的基本algorithm是一样的
学习libxdiff版本可能会更容易,以了解如何工作。

 /* * diff-delta.c: generate a delta between two buffers * * This code was greatly inspired by parts of LibXDiff from Davide Libenzi * http://www.xmailserver.org/xdiff-lib.html * * Rewritten for GIT by Nicolas Pitre <nico@fluxnic.net>, (C) 2005-2007 */ 

更多关于Git Book的包装文件 :

packfile格式

Git增量编码是基于复制/插入的。

这意味着派生文件被编码为一系列可以表示复制指令的操作码(例如:从基本文件拷贝y字节,从偏移量x开始到目标缓冲区)或者插入指令(例如:将下一个x字节插入到目标缓冲区)。

作为一个非常简单的例子(摘自“Delta Compression的文件系统支持”),考虑我们要创build一个delta缓冲区来将文本“proxy cache”转换为“cache proxy”。 由此产生的指示应该是:

  1. 从偏移量7复制5个字节(从基本缓冲区复制“caching”)
  2. 插入两个空格
  3. 从偏移量0复制5个字节(从基本缓冲区复制'代理')

翻译成git的编码变成:

(字节1-3代表第一条指令)

  • 0x91(10010001),被分割成
    • 0x80(10000000)(最高有效位设置为“从基址到输出的复制”指令)
    • 0x01(00000001)(表示“前进一个字节,并将其用作基准偏移量)
    • 0x10(00010000)(提前一个字节并将其用作长度)
  • 0x07(偏移量)
  • 0x05(长​​度)

(字节4-6代表第二条指令)

  • 0x02(因为MSB没有设置,这意味着'插入接下来的两个字节到输出')
  • 0x20(空格)
  • 0x20(空格)

(字节7-8代表最后的指令)

  • 0x90(10010000),被分割成
    • 0x80(10000000)(意思是“复制”)
    • 0x10(00010000)(提前一个字节并将其用作长度)
  • 0x05(长​​度)

请注意,在最后的复制指令中没有指定意味着偏移量0的偏移量。当需要更大的偏移量/长度时,复制操作码中的其他位也可以被设置。

结果增量缓冲区在这个例子中有8个字节,由于目标缓冲区有12个字节,所以压缩量并不大,但是当这个编码应用于大的文本文件时,它可以产生巨大的差异。

我最近推送了一个node.js库到github,它使用git增量编码实现diff / patch函数。 这个代码应该比git源代码更易读,更易于评论,而git源代码已经经过了很多优化。

我也写了一些testing ,用与上面类似的格式来解释每个示例中使用的输出操作码。

这个algorithm是否被标准化,并在其他工具中使用?

包格式是公共API的一部分:用于推送和提取操作的传输协议使用它来通过networking发送较less的数据。

除了参考: JGit和libgit2之外,至less还有两个主要的Git实现。

因此,这种格式不可能有倒退的变化,在这个意义上可以被认为是“标准化的”。

来自文档的这个惊人的文件描述了在包algorithm中使用的启发式algorithm,作为Linus的电子邮件中的一个有趣的评论: https : //github.com/git/git/blob/v2.9.1/Documentation/technical/pack-heuristics。文本