git是否在文件之间重复删除?

Tor*_*erg 10 git

如果我的存储库包含相同文件的几个副本,只有很小的更改(不要问为什么),git会通过仅存储文件之间的差异来节省空间吗?

tor*_*rek 13

可以,但很难说它是否.在某些情况下,保证它不会.

要理解这个答案(及其局限性),我们必须看看git存储对象的方式..git/objects/这个stackoverflow答案Pro Git书中有一个很好的描述"git对象"的格式(存储在其中).

当存储像这样的"松散对象" - git为我们称之为"活动"对象的东西 - 它们是zlib缩小的,正如Pro Git书所说,但没有以其他方式压缩.因此,存储在两个不同对象中的两个不同(不是位相同的)文件永远不会相互压缩.

另一方面,最终对象可以"打包"到"包文件"中.有关包文件的信息,请参阅Pro Git书籍的另一部分.存储在包文件中的对象对同一文件中的其他对象进行"增量压缩".准确地说,git用什么标准来选择哪些对象被压缩而其他对象非常模糊.这是Pro Git Book的一个片段:

当Git打包对象时,它会查找名称和大小相似的文件,并仅存储从一个版本的文件到下一个版本的增量.您可以查看packfile并查看Git为节省空间所做的工作.git verify-pack管道命令允许您查看打包的内容[...]

如果git决定delta-compress"大文件A的包条目"与"大文件B的包条目",那么 - 只有这样 - 才能以你问的方式git节省空间.

Git每次git gc运行时都会生成包文件(或更确切地说,通过git pack-objectsgit repack更高级别的操作,包括git gc在需要/适当时为您运行这些文件).此时,git收集松散的对象,和/或爆炸并重新打包现有的包.如果此时关闭但不完全相同的文件相互之间进行增量压缩,您可能会看到一些非常大的空间节省.

但是,如果您继续修改文件,则将在工作树中处理扩展和未压缩的版本,然后git add处理结果.这将创建一个新的"松散对象",并且根据定义,不会对任何东西进行增量压缩(没有其他松散对象,也没有任何包).

克隆存储库时,通常git会从要传输的对象中生成包(甚至是"瘦包",这些包不是独立包),因此通过Intertubes发送的包尽可能小.因此,即使对象在源存储库中松散,您可以获得增量压缩的好处.再一次,一旦你开始处理这些文件(将它们变成松散的对象),你就会失去好处,并且只有在松散的物体被再次打包并且 git的启发式压缩它们时才重新获得它.

这里真正的要点是,要找到答案,您可以使用Pro Git手册中概述的方法进行尝试.


Emi*_*yan 5

git仅通过存储文件之间的差异来节省空间吗?

是的,git可以将文件打包为压缩格式。

您的磁盘上有两个几乎相同的4K对象。如果Git可以完整地存储其中一个,然后将第二个对象仅存储为它和第一个之间的增量,那不是很好吗?

事实证明可以。Git将对象保存在磁盘上的初始格式称为宽松对象格式。但是,为了节省空间并提高效率,Git有时会将其中的几个对象打包到一个称为packfile的二进制文件中。如果周围有太多松散的对象,git gc 手动运行命令或推送到远程服务器,则Git会执行此操作。要查看会发生什么,您可以通过调用以下git gc命令手动要求Git打包对象: