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

时间:2014-09-04 09:32:40

标签: git

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

2 个答案:

答案 0 :(得分:12)

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

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

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

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

  

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

如果git决定delta-compress“大文件A的包装条目”与“大文件B的包装条目”,那么 - 和然后 - 可以按照你问的方式git节省空间

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

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

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

真正的要点是,要找出答案,您可以使用Pro Git book中列出的方法轻松尝试。

答案 1 :(得分:5)

  

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

是的,git可以pack the files为压缩格式。

  

磁盘上有两个几乎相同的4K对象。不是吗   如果Git可以存储其中一个而不是第二个对象,那就太好了   仅作为它与第一个之间的差异?

     

事实证明它可以。 Git保存的初始格式   磁盘上的对象称为松散对象格式。但偶尔也会   Git将这些对象中的几个打包成一个名为的二进制文件   一个packfile,以节省空间并提高效率。 Git这样做   如果您周围有太多松散的物体,如果您运行git gc   手动命令,或者如果您推送到远程服务器。看什么   碰巧,您可以手动要求Git通过调用打包对象   git gc命令: