关于Git的对象
数年前我读了《Pro Git》时的总结部分仍然保存在我的草稿中,作为悼念,我选择发表。
这是什么样的便签?
有关.git/objects文件夹中文件的关系的备忘录。
关于对象
UNIX 是一个所有东西都是文件对象的操作系统。Git 也遵循了这个原则。
通过提交(commit),将生成一些对象,比如文件。
具体来说,会生成提交对象(commit object)、树对象(tree object)、块对象(blob object)(技术上略有不同)。
blob对象相当于”文件”
tree对象相当于”目录结构”
这些对象实体是存储在.git/objects目录下的文件。
目标文件的本质
当打开.git/objects目录下的文件时,可以看到以16进制的40个字符为名称的文件存在。
其中的内容是文件的内容和不可分割的哈希值。
blob中包含了一个目录名称和经过zlib压缩的“文件”的内容。
由于blob的名称是“文件”内容的哈希值(SHA-1),所以blob的名称和内容成为不可分割的(除非出现天文学上的概率)。
blob不保存原始“文件”的名称、权限等元信息,这些信息由tree对象保存。
tree对象中包含了blob的元信息、引用以及子tree的引用。
在根目录树的所有者和权限信息等方面,由谁持有呢?
实际上,这是由提交对象所持有的。
提交对象中包含了对根目录树的引用、对父提交对象的引用、提交历史的消息、时间戳等内容。
当blob对象发生改变时,文件名的哈希值也会发生变化。因此,与该blob相关的tree会发生变动。
然后,tree文件的文件名哈希值也会改变。然后,这个tree的父tree也会发生变化,一直到根部的tree都会被修改。
而且,还会对具有根tree元信息的commit进行更改,最终会影响到根commit对象。
印象
当blob对象发生变化时,这种变化会传播到commit对象,这一点非常出色。