Git原理--4、Git对象和存储原理-Commit对象
1. Commit对象介绍
现在来介绍最后一种Git对象commit
对象,也叫提交对象。
提交对象可以理解为是对树对象的一层封装,提交信息包括基于当前暂存区中索引文件生成的tree
对象,还有包含了提交时间,提交者信息,作者信息,以及提交备注等内容,更重要的是里面还包含了父提交的ID(第一次提交没有父提交ID),由此就可以形成Git提交的有向无环图。(是链式的关系,把所有commit
对象关联起来)
即:commit
对象通常指向一个 tree
对象,并且封装了文件的提交时间,提交者信息,作者信息,提交备注,以及父提交引用等数据。
下面是commit
对象的存储结构:
2. Commit对象说明
我们通过练习来说明commit
对象,接着用前面Tree
对象的本地版本库。
(1)创建一个commit
对象
我们可以通过调用commit-tree
命令创建一个提交对象,为此需要指定一个树对象的SHA-1
值,以及该提交的父提交对象。
说明:使用
commit-tree
命令来创建提交对象,一般都需要和父提交进行关联,如果是第一次将暂存区的文件索引数据提交到本地版本库,那么该提交操作就不需要指定父提交对象。
1)我们可以先查看一下此时Git本地库中的对象,如下:
演示代码请看上一节Git原理--3、Git对象和存储原理-Tree对象
1 |
|
2)我们通过第一个树对象,创建一个commit
对象
1 |
|
说明:
tree
:表示该commit
对象所指向的tree
对象的索引author
:表示该文件的作者。committer
:表示该文件的提交者。first commit
:这段文本是提交备注。(备注与前面留空一行)- 因为是第一次进行
commit
提交操作,所以没有父提交信息。 1618190880 +0800
:表示时间,一个时间戳。
即:
commit
对象的格式很简单:指明了该时间点项目快照的顶层树对象、作者/提交者信息(从 Git 设置的user.name
和user.email
中获得),以及当前时间戳、留空一行,最后是提交注释。
提示:
git commit-tree
命令不但生成了提交对象,而且会将对应的快照(树对象)提交到本地库中。
因为加了时间戳,所以每次执行,commit对象的SHA-1是不一样的
(2)创建第二个commit
对象
根据第二个tree
对象和第一个commit
对象,来创建第二个commit
对象。
通过-p
选项指定父提交对象。
1 |
|
1 |
|
提交对象的格式很简单:
它先指定一个顶层树对象,代表当前项目快照;
然后是可能存在的父提交;
之后是作者/提交者信息(依据你的
user.name
和user.email
配置来设定,外加一个时间戳);留空一行,最后是提交注释。
3. 本地库中对象之间的关系
我们可以查看一下此时Git本地库中的对象
1 |
|
可以从上面看到,此时的本地版本库中共有9个对象,三个blob
对象,三个tree
对象,三个commit
对象。
他们之间的关系如下图:
4. 总结
- 提交是我们经常使用的Git动作,每次提交操作都指向一个树对象,同时会产生一个
commit
对象。
即:一个commit
对象包含了一个tree
对象,这个tree
对象记录了在那个时间点,项目包含了什么文件夹和什么文件。 - 一个提交对象可以有一个或者多个父提交。
- 每次
commit
操作都会基于当前索引文件index新建tree
对象。那么当前索引文件,是在上次提交的基础上更新来的,所以每次提交产生的commit
对象,与其他的commit
对象,都有前后关系或者称为父子关系。 - 对于我们来说,不需要直接访问
blob
对象和tree
对象,我们直接访问commit
对象就可以了。
即:commit
对象对应的tree
对象下面,又包含了小的tree
对象和blob
对象,子的tree
对象一层层展开,最后叶子节点就是一个个blob
对象,也就是一个个文件。
到这里,我们就能够清楚的了解,什么叫一个Git版本。
tree
对象才是一次项目版本的快照,提交对象是对tree
对象的一次封装。即:
- 项目的快照就是一个树对象。
- 项目的版本就是一个提交对象。
而且Git的每一个版本,存储的不是增量,而存储的是当前项目的快照。同时
objects
目录中相当于存放了项目的所有历史记录,回滚就相当的方便了,找到对应的commit
对象的hash就可以了。
5. 练习
请问下图中包含多少个tree
对象和blob
对象?
一共包含两个tree
对象,一个blob
对象,一个commit
对象。
说明:
- 一个
commit
对象一定对应一个tree
对象(这个tree
对象应该是一个完整项目仓库的快照) doc
目录下有一个blob
对象,也就是readme
文件。
6. 命令总结
Git底层命令:
git commit-tree
:生成一个commit
对象。git cat-file -t 键
:查看Git对象的类型。git cat-file -p 键
:查看Git对象的内容。