首页 > 解决方案 > Git 可以将文件容器存储为树和 blob 吗?

问题描述

Git 是一个内容可寻址的文件系统,它具有三种类型的对象:blob、树和提交。原则上,像 ZIP 这样的容器文件格式可以解释为与 Git 术语中包含树的单个文件(或链接)类似的概念。虽然 ZIP 文件和其他类型的容器在 Git 中没有任何特殊处理,但这些容器只是存储为 blob。

例如,假设我有一个 ZIP 文件,其中包含一些带有时间戳的文件(Git 不处理的时间戳)、空目录,并且可能认为需要在 Git 存储库中拥有这样的 ZIP 容器(可能是预编译的 JAR 文件,经常编辑OpenOffice 文档等)。现在,让我们考虑对容器进行了轻微修改。从 Git 的角度来看,这将创建一个完全不同的 blob,因此只要容器被反复修改,存储库就会急剧增长。我遇到了一个有趣的清洁/涂抹过滤器这会做类似的事情,但是它会破坏原始 ZIP 涂抹覆盖原始 ZIP 擦除原始条目时间戳,可能是 ZIP 注释以及 ZIP 容器可以具有的任何其他内容(+ 据我所知,它使裸存储库难以使用,因为它们不包含仅在结帐时创建的“已清理” ZIP 容器),因此该过滤器对我没有什么兴趣。

我想知道,是否可以告诉 Git 将(可能是 ZIP)容器存储为 Git 的一等公民,如内部的树和 blob?我想,虽然它不支持这种情况。


更新 1

我错了,正如人们在下面所说的那样,Git 中有四种对象类型:我错过了标记对象。但是,我认为它们是建立在像注释(可能)那样的提交之上的。

标签: git

解决方案


git 中的大多数命令确实希望在每个对象的开头找到 4 个单词blob、或中的一个tree,因此添加新的对象类型几乎是不可能的。committag

这是一个手动实验:

# I created an object with a new type 'foo' :
$ cat .git/objects/70/c52a28ff2b01f46ccc0cdd03c61c569fd6fd54 | pigz -dz; echo
foo10.abcdefghij    # the '.' is actually '\0'

# all regular git commands start with a "unable to parse header of [object]" :
$ git show 70c52a28ff2b01f46ccc0cdd03c61c569fd6fd54
error: unable to parse 70c52a28ff2b01f46ccc0cdd03c61c569fd6fd54 header
error: unable to parse 70c52a28ff2b01f46ccc0cdd03c61c569fd6fd54 header
fatal: loose object 70c52a28ff2b01f46ccc0cdd03c61c569fd6fd54 (stored in .git/objects/70/c52a28ff2b01f46ccc0cdd03c61c569fd6fd54) is corrupt

$ git fsck
error: unable to parse header of .git/objects/70/c52a28ff2b01f46ccc0cdd03c61c569fd6fd54
error: 70c52a28ff2b01f46ccc0cdd03c61c569fd6fd54: object corrupt or missing: .git/objects/70/c52a28ff2b01f46ccc0cdd03c61c569fd6fd54
Checking object directories: 100% (256/256), done.

# etc ...

一种可能性是编写一个更完整的涂抹/清洁过滤器,它不仅可以存储 zip 的实际内容,还可以存储所有额外的数据(例如时间戳、评论......)

这是第一个想法:

如果 archive.zip 包含dir\file.txt

  • 创建一棵树,命名为dir
  • 将目录标头存储在具有已知名称的 blob 中(dheader例如)
  • 将标题和内容存储file.txt在两个不同的 blob 中(hfile.txt例如_file.txt
  • 等其他 zip 元数据

使用不同的前缀应该可以让您在需要存储的每种类型的数据之间有一个清晰的分隔

第二个是:

  • 设法将所有档案库的元数据打包在一个 blob 中

ETC ...

然后,干净的过滤器将有足够的数据来重建相同的存档。

请注意,“重建 zip 文件”将需要 clean 过滤器来实现 zip 存档的所有可能功能(例如:能够以所有已知格式进行压缩,...)


推荐阅读