git-lfs 中的单个文件版本

Single file version in git-lfs

有没有办法设置 git-lfs 只存储 LFS 跟踪文件的一个版本?该文件的新版本应替换旧版本。在其他作品中,旧提交应该引用最新(唯一)版本的 LFS 文件。

我想这样做是为了减小存储库的大小,同时仍然能够在所有克隆之间同步最新的二进制文件。我不需要跟踪对放入 LFS 的文件所做的更改。

例如,如果 elephant.bin 被修改,我希望在添加新的 elephant.bin 之前从 .git/lfs/objects 中删除原来的 elephant.bin ].

我正在考虑使用指向二进制文件的符号链接或试图找出 git-附件来执行此操作。因为那些应该实现我的目标。然而,如果有一种方法可以避免管理符号链接并坚持使用流行的 git-lfs,那是首选。

我找到的最接近的相关问题是 Multiple file versions in git-lfs

这不能合理地用开箱即用的 LFS 功能来完成。在 git 中,每一点内容都是包含该内容的提交的组成部分;即使使用 LFS[1] 也是如此。最重要的是,每次更改其中一个文件时,您都必须重写整个存储库的历史记录。这做起来很麻烦,而且如果其他人有回购的副本,每次重写历史都会毁掉他们的克隆。

我试着想清楚你必须做些什么才能使这样的东西起作用。使用挂钩和过滤器的组合,您至少可以非常接近 - 但它会做很多工作,我看不出如何让它正常工作,坦率地说,它没有多大意义。

没有太多意义的原因是,LFS 已经 允许您通过修剪不再相关的对象来控制本地 LFS 存储的大小。确实,如果您签出一个旧提交(不抑制 LFS),您将重新下载您已修剪的任何文件;所以如果你绝对必须保留文件的最新版本,即使在检查历史版本时(而不是简单地愿意容忍这种行为),或者如果在 2018 年以某种方式你甚至无法为你的中央 LFS 找到足够的存储空间store 来保留所有版本,那么你需要想出一些其他的解决方案。

但如果是这样,您需要在 LFS 之外寻找该解决方案。


[1] - 如果您想了解有关该声明的更多详细信息:LFS 使用您文件的 SHA256 哈希作为该文件的 "filename"。说一个文件的两个不同版本不太可能哈希到相同的 "filename" 是一种轻描淡写的说法。 LFS 在 git 存储库中存储的是一个 "pointer file",编码方式与 git 控制下的任何其他文件一样(BLOB),其内容包括 LFS 对象的 "filename".所以在LFS控制下改变文件的内容会改变指针文件的内容。

现在,git 中的 BLOB 是使用 SHA 哈希命名的。虽然这比 SHA256 的位数少,但相信任何两个不同的 BLOB 将散列为相同的 ID 仍然是不合理的。 (事实上​​ ,如果在单个 repo 中确实发生了这种情况,它将中断 git;但没有人会担心数学。)所以在 LFS 中更改文件的版本会更改指针文件在回购

从这里开始就差不多了。 BLOBTREE 中列出(及其 ID);因此 TREE 的内容必须更改,因此 TREE 的 ID 必须更改。 TREE 可能会在另一个 TREE 下列为 "subdirectory",如果这样,TREE 的 ID 会发生变化,依此类推,直到最终到达根 TREECOMMITCOMMIT 元数据包含 TREE ID,因此即使 COMMIT ID 也必须更改。

一旦 COMMIT ID 必须更改,这意味着您正在谈论完全不同的 COMMIT

因此,即使涉及 LFS,也确实不可能更改现有提交的内容。您可以创建一个略有变化的提交副本,但将其替换到历史记录中是重写。