git - Git 为哪些类型的二进制文件保留增量?

标签 git git-lfs

我们正在处理一个非常大的项目,需要迁移到 Git。不幸的是,它还包含大量二进制文件,其中一些是 zip-s、dll-s 等。目前,无法从版本控制系统中删除这些二进制文件。

我想了解更多关于 Git 如何保留二进制文件的增量以及是否保留以及不保留哪些增量的信息。我知道这可以通过 .gitattributes 进行配置文件,但是文件类型是否需要明确列出,或者是否有一个预定义的默认设置可以自动识别和处理......?

最佳答案

首先,让我们先了解一些术语。文件存储为 blob 对象。这些是四种对象类型之一,其他三种是提交、树和带注释的标签。

Git 的模型是所有对象在逻辑上都是独立的。一切都通过其哈希 ID 键存储在数据库中。要检索任何对象,您首先要知道它的散列 ID,这是您从某物或其他人那里获得的。1 您将该散列 ID 提供给对象 getter ,它要么查找直接存储该对象的对象,而没有机会在 delta 压缩中——这就是 Git 所说的松散对象——或者,如果失败了,Git 会查看打包文件,这些文件将多个单独的对象打包在一起,并提供了进行 delta 压缩的机会。 2

那么,您要查找的是有关 Git 选择对这些包文件中的其他 blob 对象进行增量压缩的 blob 对象的信息。答案随着时间的推移而有所变化,因此没有单一的正确答案——但有某些控制旋钮,包括 .gitattributes你提到的一个。

实际的增量格式是 modificationxdelta .从字面上看,它可以针对任何其他二进制数据压缩(或“删除”)任何二进制数据——但结果会很差,除非输入选择得当。输入选择才是真正的关键。 Git 还有一个 technical documentation file describing how objects are chosen for deltification .这会考虑文件路径名称,尤其是最终路径组件名称。

请注意,如果 deltification 未能使对象变小,则该对象根本没有经过 delta 压缩。对象的原始文件大小也是这里的输入,core.bigFileThreshold (在 Git 1.7.6 中引入)设置大小值:高于此级别的文件根本不会被删除。

因此,您可以通过以下两种方式之一阻止 Git 考虑将文件(实际上是对象)进行删除:

  • 套装core.bigFileThreshold以至于对象太大,或者
  • 使对象的路径名匹配 .gitattributes具有 -delta 的行指定的。

  • 请注意,在使用 Git-LFS 时,大文件根本不会存储在 Git 中。相反,一个大文件(由 Git-LFS 设置定义)被一个间接名称替换(在 git add 时间)。 Git 然后将此间接名称存储为 blob 对象(使用原始文件的路径)。当 Git 提取对象时,Git-LFS 在允许它进入你的工作树之前检查它。 Git-LFS 检测到对象的数据被替换为间接名称,并使用间接名称从另一个(单独的,非 Git 的)服务器检索“真实”数据。所以 Git 根本看不到大文件的数据:相反,它只看到这些间接名称。

    1例如,我们可能以分支名称开头,如 master ,它为我们提供最新(或提示)提交哈希 ID。该哈希 ID 使我们可以访问提交对象。提交列出了树的哈希 ID。树,一旦我们获得它,就会列出一些 blob 的哈希 ID 以及文件名。所以,现在我们知道 README 版本的哈希 ID在 master 的提示提交中,如果这就是我们正在寻找的。或者,我们使用提交数据来查找较旧的提交,然后使用它来查找另一个更旧的提交,依此类推,直到到达我们想要的提交;然后我们使用树来查找文件的 blob ID(和名称)。

    2通常情况下,一个对象只能针对同一包中的其他对象进行“deltified”。出于传输目的,Git 提供了它所谓的瘦包,其中对象可以针对其他被省略的对象进行增量压缩,但假定在传输机制的另一侧可用。另一个 Git 必须“增肥”瘦包。

    关于git - Git 为哪些类型的二进制文件保留增量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48301920/

    相关文章:

    git - 将外部更改 merge 到我的 Git 存储库的最佳方式是什么?

    git - 获取 git LFS 文件时出错 : Object does not exist on the server: [404] Object does not exist on the server

    git checkout 需要几个小时

    git - 从 git LFS 中提取所有文件

    Git 主目录

    git - 如何从 github pull 我的项目?

    git - 让 'git diff' 忽略 ^M

    git - 我可以让 git 不 merge 文件,而只是复制新文件吗

    linux - 删除不在 repo 中的 git LFS 文件

    git-p4 和配置 git-p4.largeFileExtensions