在.git目录下各项的含义一文中介绍了各个对象的含义,本文探讨一下.git目录下objects目录的含义。
objects ---- 存储所有数据内容
那他是如何存储的呢?
要搞清楚存储,先了解git的三个对象:
下面来做一次修改-> 暂存 -> commit的动作,观察objects目录的变化。
初始化之后的.git/objects目录为空
git init
find .git/objects
现在我们新增一个文件和目录,并在文件中写入内容。
mkdir testdir
echo "This is a testdir_test." > testdir/dirtest
echo "This is a test." > testfile
find .git/objects
此时查看objects目录,没有任何变化。
将新增内容添加至缓存区,然后观察.git/objects目录。
git add .
find .git/objects
可以看到新增了一个48、49目录以及48目录下新增了一个4ba93ef5b0aed5b72af8f4e9dc4cfd10ef1a81文件,49目录下增加了d4e48106fa134dbff2717da02191eef8133dd,没错都是38位,加上前面两位就是40位SHA1值,git在存储这个对象的时候,以前两位作为目录名,后38位作为文件名存放。
可以通过 git cat-file 命令查看他到底是个什么对象。
# 加上目录名,拼接出SHA1值
git cat-file -t 484ba93ef5b0aed5b72af8f4e9dc4cfd10ef1a81
# 读取数据
git cat-file -p 484ba93ef5b0aed5b72af8f4e9dc4cfd10ef1a81
git cat-file -t 49d4e48106fa134dbff2717da02191eef8133dd8
git cat-file -p 49d4e48106fa134dbff2717da02191eef8133dd8
可以看到存储的blob对象,对应的就是文件内容,也就是说实际文件内容被当做blob对象存在了git仓库目录中。
那执行commit之后呢?
git commit -m "first commit"
git log
find .git/objects
通过 git log生成已经生成了commit(提交对象)
观察.git/objects 又多出了
- .git/objects/f6/642d102fc78914077261c13b79b3ff1339e831
- .git/objects/35/b447c5ce897e4e3a8f12d9f7cdc963ce84ce84
- .git/objects/80/57969b716973f32fba1db177e14163191ba65d
还是借助git cat-file命令继续观察。
git cat-file -t f6642d102fc78914077261c13b79b3ff1339e831
git cat-file -p f6642d102fc78914077261c13b79b3ff1339e831
git cat-file -t 35b447c5ce897e4e3a8f12d9f7cdc963ce84ce84
git cat-file -p 35b447c5ce897e4e3a8f12d9f7cdc963ce84ce84
git cat-file -t 8057969b716973f32fba1db177e14163191ba65d
git cat-file -p 8057969b716973f32fba1db177e14163191ba65d
f6642d -- 树对象,存储的是testdir 这个目录名
35b447 -- 树对象,他指向了f6642d树对象和484ba9 blob块对象
805796 -- 提交对象,保存了指向的顶层树信息和提交相关信息
环环相扣,那我们是否可以这样理解,Git所做的工作实质就是将被改写的文件保存为数据对象, 更新暂存区,记录树对象,最后创建一个指明了顶层树对象和父提交的提交对象。
哦,原来是树。