Git的目录结构
摘要: 本文介绍了Git的目录结构及其核心对象,包括.git目录的组成、objects目录中的blob、tree和commit对象的存储方式。作者详细阐述了每个对象的作用:blob存储文件内容,tree存储文件名、类型和指向blob或子tree的指针,commit包含提交信息、父commit和对应的tree。通过示例演示了Git如何以内容为基础进行存储,强调Git保存的是文件的完整副本而非差异,并指出所有内容都由指针指向,体现了Git的内容寻址和版本管理机制。 (评价: A)
git目录
新建一个git项目,查看.git目录
|
|
objects
我的理解是,项目中你看到的每个东西都是一个object,实际上object有:commit、tree、blob、tag(加tag的时候才会有)
- 添加一个文件
|
|
通过以上的信息,实际上一次commit是构建了一棵树。
以上:
9759->f253->58c9 || commit->tree->blob
如果修改a.txt的内容,可以看到会生成新的objects,并且有一个新的blob完全包含了新的a.txt的全部内容,这意味着,git是保存文件的完全的副本,而不是差异。同时会有新的commit object 和 新的tree object。实践吧!
添加了b.txt的objects tree
|
|
可以试着reset一下,会发现其实所有的objects都还在的,只是改变了HEAD等指针;
git的所有内容都是实例和指向它的指针。
[以下在git magic]
blob
Git基于“内容寻址”:文件并不按它们的文件名存储,而是按它们包含内容的哈希值, 在一个叫“blob对象”的文件里。我们可以把文件内容的哈希值看作一个唯一ID,这样 在某种意义上我们通过他们内容放置文件。开始的“blob 6”只是一个包含对象类型与 其长度的头;它简化了内部存储。
这样我可以轻易预言你所看到的输出:文件名是无关的:只有里面的内容被用作构 建blob对象。
你可能想知道对相同的文件会发生什么。试图填加一个你文件的拷贝,什么文件名都行。 在 .git/objects 的内容保持不变,不管你加了多少。Git都只存储一次数据。
以下内容hash值:
"blob" SP "6" NUL "[内容]" LF
以上, blob结构是, 按照文件内容生成的,只要内容相同, 就是同一个blob
tree
“tree”对象:一组包含文件类型,文件名和哈希值的数据。在我们的例 子里,文件类型是100644,这意味着“rose”是一个一般文件,并且哈希值指blob对象, 包含“rose”的内容。其他可能文件类型有可执行,链接或者目录。在最后一个例子里, 哈希值指向一个tree对象。 以上, tree结构是, 包含了文件名/类型(一般文件/可执行/链接/目录),和其指向的对象(目录指向tree, 一般指向blob)
以下内容hash值:
"tree" SP "32" NUL "[文件类型] 文件名" NUL 0xaa823728ea7d592acc69b36875a482cdf3fd5c8d[指向的对象]
commmit
commit 结构, 会包含commit信息/作者等, 会包含父commit指针, 包含tree指针