赞
踩
系列的第一篇文章中这样写道:
通过提交对象的父提交和子提交属性,所有的提交记录就形成了一条提交链。广义上,我们将提交链称之为分支。
这里出现的提交对象就是 Git 对象中的一种。
Git 对象共有三种:数据对象(blob object)、树对象(tree object)、提交对象(commit object)。
数据对象:作为 Git 对象中最底层的对象,数据对象代表的是文件的内容。没错,只是文件的内容,文件名并不由数据对象负责,而是由树对象管理。
树对象:树对象不仅能解决文件名保存的问题,还可以让我们将多个文件组织到一起。
提交对象:提交对象大概是我们最熟悉的对象。它包含一个顶层树对象,代表当前项目快照;然后是可能存在的父提交(首次提交就没有父提交);之后是作者信息(依据你的 user.name 和 user.email 配置来设定,外加一个时间戳);留空一行,最后是提交注释。
我们知道每个提交对象都有由40个字符组成的 SHA-1 值,其实不仅是提交对象,数据对象和树对象也有代表唯一的 SHA-1 值。
通过下面的指令,我们可以查看 Git 对象中存放的大致内容:
git cat-file -p <SHA-1>
Git 对象实体存放在 .git/obejcts 目录下,路径为 Git 对象 SHA-1 值的前 2 位作为子目录名,后 38 位作为子目录下的文件名。
初始化 Git 仓库,进行一次提交。此时仓库中的文件信息如下:
各文件的内容如下所示:
查看提交日志:
查看提交对象的内容:
正如上文所说的,提交对象包含一个顶层树对象、作者信息、留空一行以及提交注释。
接着查看顶层树对象的内容:
该对象中包含一个树对象以及两个数据对象。分别查看三个 Git 对象中的内容:
对比上面两张图中的信息我们可以发现,树对象的内容对应的是某个目录下的文件信息(例如顶层树对象对应的就是仓库目录),数据对象的内容对应的是某个具体的文件中的信息。
至此为止共出现过 6 个 Git 对象:一个提交对象,两个树对象以及三个文件对象,它们的 SHA-1 值如下所示:
提交对象 SHA-1 值:031b79a3f50bac0aba1bb294d30ba5c7ea939b8e
树对象 SHA-1 值:a5cfff3bbf0c3e9120d1c1e3383b86b85dcdcbc5、145f45b5ccc42c52cd41d66a069a0b3679ae5e05
数据对象 SHA-1 值:433eb172726bc7b6d60e8d68efb0f0ef4e67a667、f138820097c8ef62a012205db0b1701df516f6d5、a309e46e332a0f166453c6137344852fab38d120
由于这 6 个 Git 对象的 SHA-1 值的前两个字符都没有重复,所以 .git/objects 目录下应该出现 6 个存放 Git 对象实体的子目录。
查看 .git/objects 目录下的文件信息:
6 个 Git 对象之间的关系如下图所示:
以前听说每次提交 Git 都会以全量的方式保存仓库中的文件信息,当时我以为 Git 会将整个仓库中的文件全部拷贝一份作为项目快照,但深入了解 Git 对象之后发现事实并不是这样。
向 file1 中增加新内容,再次提交:
如果 Git 将整个仓库中的文件拷贝一份作为历史快照,那么此时 .git/objects 目录下应该有 12 个 Git 对象实体。
查看 .git/objects 目录下的文件:
可以看到,此时 .git/objects 目录下只有 9 个文件(即 9 个 Git 对象实体),也就是说第二次提交只产生了 3 个新的 Git 对象。
这 3 个新的 Git 对象的 SHA-1 值如下:
b7b0a3c01945ed7127dbb1f7c569d4f4373efc66、469bfdcf04e804dfeb50e182aac76a5a90af4c6f、167b604fa17000016e1c7c60cff48369bf5e7e85
分别查看 3 个 Git 对象的内容:
从上图中可以看到,三个新增的 Git 对象分别为:第二次提交后生成的提交对象、新提交对象包含的顶层树对象、修改文件后的产生的数据对象。
因此如果文件没有修改,提交时 Git 并不会存储该文件的全量信息,而是保留一个链接指向之前存储的文件。
第二次提交后,Git 对象之间的关系如下图所示:
参考:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。