为什么git将对象存储在具有散列的前两个字符的目录中?

Mon*_*ing 22 git directory-structure

我正在设计一个基于UUID的目录结构,所以我正在看git做什么来看它是不是一个好模型.

我可以看到git将对象存储在一个结构中,其中哈希的前两个字符用作目录,其余的哈希是文件名.

我想知道为什么?如果使用目录有一个很大的优势,为什么不创建更多的子目录...说一个目录为哈希创建一个树的每一个或两个字符?如果没有很大的优势那么为什么带有前两个字符的目录呢?

tor*_*rek 21

01/23456789abcdef0123456789abcdef01234567当松散对象的数量超过魔术常量时(默认为6700但可配置),Git从"松散对象"(在名为的文件中)切换到"包" gc.auto.由于SHA-1值往往分布均匀,因此可以通过查看单个目录来近似总松散对象.如果其中一个目标目录中有超过(6700 + 255)/ 256 = 27个文件,则需要一个包文件.

因此,不需要额外的扇出(01/23/4567...):你不可能在一个目录中获得那么多的对象.事实上,更大的扇出会使得更难以发现是时候自动打包,除非你设置的阈值更高(超过6700),因为(27 + 255)/ 256是1 - 所以你我想把所有东西都算在内01/*/而不仅仅是01/.

人们可以使用0/1234567...并允许每个目录最多~419个对象来获得相同的行为,但是线性目录扫描(在任何仍然使用它们的系统上)是O(n 2),而27 2只是729,而419 2是175561. [编辑:这仅适用于文件创建,您有两阶段搜索,一次查找可以创建,第二次查找插槽或追加.查找仍然是O(n).]

  • @torek你碰巧有你的答案来源吗?这非常有趣,我找不到关于这个主题的更多信息(git的设计决策/存储大量文件) (4认同)
  • @Yaurthek:我在git源代码中发现了一些注释,可能还有一些分散在邮件列表中的项目.然后自己做了一些算术,看了看我的各种git回购.从Usenet以N位数字名称存储每个文件的日子来看,"旧"(非Btree目录)Unix风格文件系统上的目录行为是众所周知的. (3认同)