Git目录结构中的奇怪路径

时间:2014-03-23 18:11:26

标签: git

我在.git目录中看到了以下路径。

.git/object/3b/12abef878787483abeceddaa5544489abff789a

当infact SHA为3b12abef878787483abeceddaa5544489abff789a

这是文件内容的SHA,因此应该在没有/的情况下存储。 为什么git将blob存储在这条奇怪的路径中,这样做有什么好处?

1 个答案:

答案 0 :(得分:7)

原因是要防止一个目录中有太多文件。使用存储在子目录3b中的所有SHA值3b,任何单个目录上的工作负载都是1/256 th ,如果所有的blob在一个目录中。最终,这会加快性能;寻找特定blob的搜索次数较少。

您可以在terminfo目录中看到类似的效果,其中条目根据终端条目的第一个字母细分为目录。 CPAN系统的命名层次结构中有authors/id/A/AA/AARDVARK


  

请为我详细说明一下。

假设git想要找到blob 3b12abef878787483abeceddaa5544489abff789a并且目录分区方案未被使用。为了争论,可能会有512个blob,并且要访问该文件,内核可能必须读取.git/objects中的所有512个目录条目才能找到正确的条目。

现在假设目录分区方案正在使用中,并且由于统计错误的奇迹,有256个子目录,每个子目录包含2个文件。现在,最坏的内核必须在./git/objects目录中读取每个条目中具有2字节名称的256个目录条目(与具有32个字节名称的512个目录条目相比),然后必须读取最差2个条目./git/objects/3b目录中的30个字节的名称。

存在复杂因素,例如不完美平衡的散列和内存缓存以及磁盘访问,但一般的想法是将文件分发到多个子目录意味着操作系统内核查找文件的工作量较少。如果目录中的文件数量将扩展到数百个,那么值得考虑将其分解。