git如何存储重复文件?

Jos*_*shJ 21 git

我们有一个包含SVM AI输入数据和结果的Git存储库.每次运行新模型时,我们都会为该模型创建一个新的根文件夹,以便我们可以随时组织结果:

/run1.0
  /data
    ... 100 mb of data
  /classification.csv
  /results.csv
  ...
/run2.0
  /data
    ... 200 mb of data (including run1.0/data)
  /classification.csv
  /results.csv
  ...
Run Code Online (Sandbox Code Playgroud)

在我们构建新模型时,我们可能会从之前的运行中获取数据(大型.wav文件).这意味着我们的数据文件夹2.0可能包含1.0 /数据中的所有文件以及我们可能收集的其他数据.

如果我们继续这样做,回购很容易超过千兆字节.

Git是否有办法识别重复的二进制文件并仅存储一次(例如像符号链接)?如果没有,我们将重新设计数据的存储方式.

Dav*_*ton 23

我可能不会解释这个问题,但我的理解是每个提交只存储一个树结构,表示项目的文件结构,并指向存储在objects子文件夹中的实际文件.Git使用文件内容的SHA1哈希来创建文件名和子文件夹,例如,如果文件的内容创建了以下哈希:

ob064b56112cc80495ba59e2ef63ffc9e9ef0c77
Run Code Online (Sandbox Code Playgroud)

它将存储为:

的.git /对象/ OB/064b56112cc80495ba59e2ef63ffc9e9ef0c77

前两个字符用作目录名,其余字符用作文件名.

结果是,即使您有多个文件具有相同的内容但不同的名称或位于不同的位置或来自不同的提交,也只会保存一个副本,但在每个提交树中都有几个指针.

  • pastebin.com/p0KpqBPX对于那些懒得去实验的人来说:)相同的对象,只需要比.git/objects中的1个文件稍微多一点的空间 (2认同)

mat*_*aly 7

默认情况下/本身:不是.

Git的工作原理是它创建文件的快照,而不是像其他VCS那样的增量差异.

编辑

正如Dave和opatut所提到的,我对git如何存储文件的理解是不正确的,我为造成的混乱道歉.在进行更多研究后,Git会将重复的文件存储为1个文件的指针.在接受这个问题的答案中引用VonC ,

...具有相同内容的多个文件仅存储一次.

还请注意,正如答案中所提到的,概念上 ......

引用git-scm文档:

Git认为它的数据更像是一组微型文件系统的快照.每次你在Git中提交或保存项目的状态时,它基本上都会记录当时所有文件的外观,并存储对该快照的引用.为了提高效率,如果文件没有改变,Git不会再次存储文件,只是指向它已存储的上一个相同文件的链接.Git认为其数据更像是一个快照流.

但是,在存储级别上,仍然使用增量,其中Git尝试尽可能快地基于启发式选择blob生成最小可能的增量,有优化压缩的选项.这将减少存储库的大小.

另外,通过opatut在其评论输出的pastebin链接中测试,重复对象仅存储一次.这意味着git将识别重复的二进制文件并仅存储一次.这是原始问题所要求的.以下是处理重复文件的其他选项.

其他选择:符号链接

您可以设置符号链接到以前的文件,当您处理它们时,它们将指向相同的大文件,但请注意,git不会跟踪符号链接指向的文件,这意味着它们只会存储符号链接.这样可以满足您减少空间的需求,同时牺牲可移植性,也就是说,如果您移动到另一台开发机器,则必须确保文件是符号链接所指向的位置.这可能不是你想要的.关于git对符号链接的作用,请参阅这个非常好的SO问答.

另一个替代方案:工具!

我找到了多种工具,可以帮助您完成管理二进制文件所需的工作.

您可以尝试git-annex,它基本上只跟踪最新版本的二进制文件,其余的由符号链接维护,所以在某种程度上这是一种更自动的方式来处理符号链接.这是他们的项目网站.

或者内置git-submodules和单独的repo来实现你想要的,你只需要获取大型二进制文件来使用它们.

诚然,我没有尝试过这些选项,所以这里是参考链接,以阅读有关它们的更多解释.参考:这个问题

  • @opatut我已经修复了我的答案并将你的pastebin添加到我的答案中,并附有评论.抱歉混乱,OP和其他人.戴夫的回答更多,他的答案应该被接受 (5认同)