git-lfs中的单个文件版本

时间:2018-08-23 22:39:42

标签: git git-lfs

是否可以将git-lfs设置为仅存储LFS跟踪文件的1个版本?文件的新版本应替换旧版本。在其他作品中,旧的提交应引用LFS文件的最新(唯一)版本。

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

例如,如果对Elephant.bin进行了修改,我希望在添加新的Elephant.bin之前从.git / lfs / objects(以及可能存储在其他任何位置)中删除原始的Elephant.bin。

我正在考虑通过与二进制文件的符号链接或试图找出git-annex来做到这一点。那些应该实现我的目标。但是,如果有办法可以避免管理符号链接并坚持使用流行的git-lfs,那是首选。

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

1 个答案:

答案 0 :(得分:1)

使用现成的LFS功能不能合理地完成此操作。在git中,内容的每一部分都是包含该内容的提交所不可或缺的。即使使用LFS [1]也是如此。最重要的是,每次更改其中一个文件时,您都必须重写整个存储库的历史记录。这样做很麻烦,而且如果其他任何人都有该存储库的副本,则每次重写历史记录都会破坏其克隆。

我已经尝试过思考完成这项工作所需要做的事情。结合使用挂钩和过滤器,您至少可以非常接近-但这将需要大量工作,我看不出如何使其正常工作,坦率地说,没有太多意义。

没有太多意义的原因是,LFS 已经使您可以通过修剪不再相关的对象来控制本地LFS存储的大小。的确,如果您签出旧的提交(不抑制LFS),您将重新下载已修剪的所有文件;因此,即使您在签出历史版本时绝对必须保留文件的最新版本(而不是简单地愿意容忍这种行为),或者如果在某种程度上在2018年,即使对于您的中央LFS也找不到足够的存储空间存储以保留所有版本,那么您需要制定其他解决方案。

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


[1]-如果您需要更多有关该声明的信息:LFS使用文件的SHA256哈希作为该文件的“文件名”。要说两个不同版本的文件不太可能散列到相同的“文件名”是一种轻描淡写的说法。 LFS在git仓库中存储的是一个“指针文件”,其编码类似于git控制下的任何其他文件(BLOB),其内容包括LFS对象的“文件名”。因此,在LFS控制下更改文件的内容将更改指针文件的内容。

现在,使用SHA哈希命名git中的BLOB。尽管它的位数少于SHA256,但仍然难以相信任何两个不同的BLOB将散列到相同的ID。 (实际上,如果确实在单个存储库中发生这种情况,它将破坏git;但是没有人理解数学。)因此,在LFS中更改文件的版本会更改存储库中指针文件的ID。

从这里开始,情况更多了。 BLOBTREE中列出(及其ID);因此TREE的内容必须更改,因此TREE的ID必须更改。该TREE可能被列为另一个TREE下的“子目录”,如果这样,TREE的ID将会更改,依此类推,直到最终到达根目录{{1} } TREECOMMIT元数据包括COMMIT ID,因此,即使TREE ID也必须更改。

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

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