git三大对象
概述:
Git对象
Git有三大对象:commit(提交对象)、tree(树对象)、blob(数据对象);所有对象都保存在.git/objects文件夹中
-
commit:是提交时的一个快照,记录着提交时的所有文件快照
-
tree:可以理解为一个文件夹,包含tree和blob对象
-
blob:一个具体文件,包含文件的内容
注意:
-
blob和自身文件名没有任何关系,只与文件内容相关,即文件相同在git中只有一份blob;
-
在文件被存放在缓存区,就会自动生成一个blob对象。当进行commit提交,就会生成tree(如果提交存在目录的话)和commit对象
演示+分析
涉及命令
-
git cat-file -t object_id:查看文件类型
-
git cat-file -p object_id:查看文件内容
-
find path: 查看path路径下的所有文件
blob对象(数据对象)
创建一个文件夹,git init 初始化git;
*验证:*初始化下的文件夹中没有git对象
[user@localhost .git]$ mkdir test && git init test && cd mkdir
[user@localhost test]$ find .git/objects/
.git/objects/
.git/objects/pack
.git/objects/info
*验证:*仅创建一个文件,并不会生成object对象
[user@localhost test]$ echo "Hello git" >> readme.txt
[user@localhost test]$ find .git/objects/
.git/objects/
.git/objects/pack
.git/objects/info
*验证:*将文件提交到暂存区,会生成blob对象;
[user@localhost test]$ git add readme.txt
[user@localhost test]$ find .git/objects/
.git/objects/
.git/objects/pack
.git/objects/info
.git/objects/0d
.git/objects/0d/ec2239efc0bbfabe4078f5357705ca93b5475e
分析:
这里我们看到的多了一个0d/ec2239efc0bbfabe4078f5357705ca93b5475e文件
-
该文件名组成方式:
源文件内容+特定头部信息,使用SHA-1散列运算而得出的。得到的散列值得前两值用于命名子文件目录,剩下的38个作为文件名。
0d:是散列值前两个值
ec2239efc0bbfabe4078f5357705ca93b5475e: 散列值剩余的38个字符
0dec2239efc0bbfabe4078f5357705ca93b5475e:这就是一个blob(数据对象)对象 -
查看类型&&内容:
[user@localhost test]$ git cat-file -t "0dec2239e" blob [user@localhost test]$ git cat-file -p "0dec2239e" Hello git
这里object_id 取前几位即可,只要标识出唯一即可查看数据
这个散列值路径文件中保存的只是源文件的一种压缩形式
-
结论:
git会将一个提交到暂存区的文件,保存为blog对象,并且blob和自身文件名没有任何关系,只与文件内容相关,即文件相同在git中只有一份blob
tree(树对象)
*验证:*创建文件,将其添加到暂存区;(结果并没有增加对象类型)
[user@localhost test]$ mkdir new_file
[user@localhost test]$ git add new_file/
[user@localhost test]$ find .git/objects/
.git/objects/
.git/objects/pack
.git/objects/info
.git/objects/0d
.git/objects/0d/ec2239efc0bbfabe4078f5357705ca93b5475e
*验证:*创建一个文件夹+内容,进行commit提交产生的对象
[user@localhost test]$ mkdir new_file && echo "hello git" >> new_file/readme.txt
[user@localhost test]$ git add .
[user@localhost test]$ git ci -m"add file"
[user@localhost test]$ find .git/objects/
.git/objects/
.git/objects/pack
.git/objects/info
.git/objects/8d
.git/objects/8d/0e41234f24b6da002d962a26c2495ea16a425f
.git/objects/bf
.git/objects/bf/2c69407e91582350eb81e10bfec19fd24b6a54
.git/objects/d2
.git/objects/d2/4f733eb56ce69c2099edfda60d739ea8a06d42
.git/objects/0b
.git/objects/0b/1bb951d5b1a4313b6e7e055b1f92db36c6c363
*验证:*输出以上四个对象类型以及查看内容
[user@localhost test]$ git cat-file -t "8d0e41234f"
blob
[user@localhost test]$ git cat-file -t "bf2c69407e"
tree
[user@localhost test]$ git cat-file -p "bf2c69407e"
100644 blob 8d0e41234f24b6da002d962a26c2495ea16a425f readme.txt
[user@localhost test]$ git cat-file -t "d24f733eb5"
tree
[user@localhost test]$ git cat-file -p "d24f733eb5"
040000 tree bf2c69407e91582350eb81e10bfec19fd24b6a54 new_file
[user@localhost test]$ git cat-file -p "bf2c69407e9"
100644 blob 8d0e41234f24b6da002d962a26c2495ea16a425f readme.txt
[user@localhost test]$ git cat-file -p "8d0e41234f2"
hello git
[user@localhost test]$ git cat-file -t "0b1bb951d5b1a"
commit
分析
查看文件内容时,前面的100644表示一个文件;040000表示一个目录
- object_id含义:
8d0e41234f:是一个blob对象,也就是创建的readme.txt 文件
bf2c69407e:为一个tree对象;(目前还不清楚为什么会多出一个目录加文件的tree,有清楚地可以在评论指出,非常感谢)
d24f733eb5:为tree对象,也就是我们创建的new_file目录。里面存放着blob对象也就是readme对象
0b1bb951d5b1a:为commit对象,提交记录
- 结论:
Git会将一个进行commit的目录存储为一个树对象进行保存, 这个树对象中会有每个子目录的树对象条目和每个文件的数据对象条目,这样就可以根据一种树结构来保存整个目录
commit(提交对象)
*验证:*commit对象中的内容
[user@localhost test]$ git cat-file -p "0b1bb951"
tree d24f733eb56ce69c2099edfda60d739ea8a06d42
author rxxxli <rxxxili.work.com> 1668177405 +0800
committer ronghaili <rxxxili.work.com> 1668177405 +0800
add file
分析
git会将commit提交的内容保存为一个快照,记录在commit对象中
-
内容含义:
tree:提交的内容树
author:提交的作者
committer:提交人
最后一行为提交描述信息
参考图:来源极客时间苏玲老师的课件
file
**分析**
git会将commit提交的内容保存为一个快照,记录在commit对象中
- 内容含义:
tree:提交的内容树
author:提交的作者
committer:提交人
最后一行为提交描述信息
*参考图*:来源极客时间苏玲老师的课件
[外链图片转存中...(img-Jhw9WSUQ-1668179155737)]