3、总结
(1)分析每个树对象的存储结构
我们可以先查看一下Git本地库中的对象,如下
.git/objects/01/ab2a43b1eb150bcf00f375800727df240cf653 # 第三个tree树对象
.git/objects/0c/1e7391ca4e59584f8b773ecdbbb9467eba1547 # test.txt第二个版本(blob对象)
.git/objects/16/3b45f0a0925b0655da232ea8a4188ccec615f5 # 第二个tree树对象
.git/objects/83/baae61804e65cc73a7201a7252750c76066a30 # test.txt第一个版本(blob对象)
.git/objects/d8/329fc1cc938780ffdd9f94e0d364e0ea74f579 # 第一个tree树对象
.git/objects/fa/49b077972391ad58037050f2a75f74e3671e92 # new.txt第一个版本(blob对象)
我们接下来用三个图,描述一下三个树对象的结构关系。
第一个树对象结构如下图:
第二个树对象结构如下图:
第三个树对象结构如下图:
也可以换Git对象类型表示:
(2)blob对象和tree对象(重点)
从上图我们可以分析出:
-
blob
对象代表文件一次次的版本。 -
tree
对象代表项目的一次次的版本。
这就是我前面2-(3)
描述过的"Git版本库中的5个对象,即表示了项目的2个版本。"
(就先这样理解)
(3)总结(重点)
暂存区的概念和相关理解:
-
所谓的暂存区
Stage
只是一个简单的索引文件而已。指的是是.git/index
文件。 -
暂存区这个索引文件里面包含的是文件的目录树,像一个虚拟的工作区,在这个虚拟工作区的目录树中,记录了文件名、文件的时间戳、文件长度、文件类型以及最重要的SHA-1值,文件的内容并没有存储在其中,所以说它像一个虚拟的工作区。
即:暂存区,也就是
.git/index
文件中存放的是文件内容的索引(快照),也可以是tree
对象的索引。 -
索引指向的是
.git/objects/
目录下的文件(Git对象)。 -
Git通过暂存区的文件索引信息来创建
tree
对象的。 -
tree
对象可以使文件内容和文件名进行关联。 -
一个树对象可以包含一条或多条记录(
tree
对象和blob
对象)。 -
暂存区内容写到版本库中后,暂存区索引内容不清空。
-
暂存区中的文件内容索引,是按对应文件覆盖的,也就是修改一个文件内容,添加到缓存区,只会把对应的文件覆盖,其他文件不会被覆盖,即:暂存区不是整体覆盖的。
暂存区的作用:除非是绕过暂存区直接提交,否则Git想把修改提交上去,就必须将修改存入暂存区最后才能commit。每次提交的是暂存区所对应的文件快照。
提示:Git对象的hash键,我们截取前几位就行,练习时对象不那么对,就不用全部都写,能够表示唯一对象就行。
4、问题
现在有三个树对象(因为执行了三次write-tree
命令),分别代表了我们想要跟踪项目的三次快照。然而问题依旧:若想重用这些快照,你必须记住这三个树对象的SHA-1
哈希值。
并且,你也完全不知道是谁保存了这些快照,在什么时刻保存的,以及为什么保存这些快照。
而以上这些,提交对象commit object
为你保存了这些基本信息。
5、本文用到的命令总结
Git底层命令:
-
git update-index --add
:把文件索引(快照)存入暂存区中。 -
git write-tree
:将当前暂存区的索引内容同步到一个树对象中。 -
git ls-files -s
:查看暂存区的文件信息。 -
git read-tree --prefix=bak
:将一个已存在的树对象添加到暂存区。 -
git cat-file -t 键
:查看Git对象的类型。 -
git cat-file -p 键
:查看Git对象的内容。
参考:
网友评论