本篇文章是对 Git 官方文档 Git Internals - Git Objects 的一个实操,帮助加深理解Git内部的对象存储结构
中文版 Git 内部原理 - Git 对象
个人翻译版本 https://blog.csdn.net/songyuequan/article/details/85862415
1. 创建一个GIt仓库
初始化仓库
git init
查看.git/objects 目录
cd .git/objects/
ls -al
2. 创建文件并暂存
创建文件
echo 'version 1' > test.txt
查看git对象目录
ls -al .git/objects/
发现此时没有任何变化
暂存文件后再次查看
git add test.txt
ls -al .git/objects/
发现此时多了一个文件对象
哈希值是83baae61804e65cc73a7201a7252750c76066a30
3. 修改文件并暂存
git add .
git status
查看.git/objects 目录
ls -al .git/objects/
ls -al .git/objects/67
发现此时总共有两个文件对象
第一个哈希值是83baae61804e65cc73a7201a7252750c76066a30
第二个哈希值是6702fe2da3140f13942b3ce09819f786acf558c1
查看hash值所对应的内容
git cat-file -p 83baae61804e65cc73a7201a7252750c76066a30
git cat-file -p 6702fe2da3140f13942b3ce09819f786acf558c1
4. 形成commit
git commit -m "init"
ls -al .git/objects/
这时发现.git/objects中多了两个对象
5ceac90a7585542e725a06bfe2aa7417aa5cea89
e8f8832a51da0ebc91b98ebf319ba7f1d5c7b07b
查看对象类型
git cat-file -t 83baae61804e65cc73a7201a7252750c76066a30
git cat-file -t 6702fe2da3140f13942b3ce09819f786acf558c1
git cat-file -t 5ceac90a7585542e725a06bfe2aa7417aa5cea89
git cat-file -t e8f8832a51da0ebc91b98ebf319ba7f1d5c7b07b
发现 e8f8832a51da0ebc91b98ebf319ba7f1d5c7b07b 是tree object5ceac90a7585542e725a06bfe2aa7417aa5cea89 是 commit object
查看commit object 内容
git cat-file -p 5ceac90a7585542e725a06bfe2aa7417aa5cea89
查看tree object 内容
git cat-file -p e8f8832a51da0ebc91b98ebf319ba7f1d5c7b07b
表明这个 tree object 只包含一个blob object
100644 表示普通文件
5. 添加一个文件再次形成提交
发现此时多了三个object
76800a225f4f704d22b1dbb64a3f4eff50970e14
a0d735098169afa9e840c711914898392ab4c73a
bb4bbfaebd767ef017a854bd902df0d5b249a802
查看对象类型
git cat-file -t 76800a225f4f704d22b1dbb64a3f4eff50970e14
git cat-file -t a0d735098169afa9e840c711914898392ab4c73a
git cat-file -t bb4bbfaebd767ef017a854bd902df0d5b249a802
查看对象内容
git cat-file -p 76800a225f4f704d22b1dbb64a3f4eff50970e14
git cat-file -p a0d735098169afa9e840c711914898392ab4c73a
git cat-file -p bb4bbfaebd767ef017a854bd902df0d5b249a802
此时我们注意到 commit object 有一个parent
bogon:ObjectTest songyuequan$ git cat-file -p 76800a225f4f704d22b1dbb64a3f4eff50970e14
tree a0d735098169afa9e840c711914898392ab4c73a
parent 5ceac90a7585542e725a06bfe2aa7417aa5cea89
author leazen.song [email protected] 1549957887 +0800
committer leazen.song [email protected] 1549957887 +0800
add one file
这个parent的ID是第一次commit的hash值
bogon:ObjectTest songyuequan$ git cat-file -p 5ceac90a7585542e725a06bfe2aa7417aa5cea89
tree e8f8832a51da0ebc91b98ebf319ba7f1d5c7b07b
author leazen.song [email protected] 1549956866 +0800
committer leazen.song [email protected] 1549956866 +0800
init
6. 修改文件内容再次形成提交
我们将 test.txt 的内容进行修改,并形成第三次commit
此时的.git/objects 目录又多了三个对象
7ba0604b9ede5e0e7be22a864367660eeda342b2
600cbb647c7a5358e85857286d9c2ec6a026a968
e6cd51e852b03986a75de394a936ceb9297108bd
查看对象类型
git cat-file -t 7ba0604b9ede5e0e7be22a864367660eeda342b2
git cat-file -t 600cbb647c7a5358e85857286d9c2ec6a026a968
git cat-file -t e6cd51e852b03986a75de394a936ceb9297108bd
查看对象内容
git cat-file -p 7ba0604b9ede5e0e7be22a864367660eeda342b2
git cat-file -p 600cbb647c7a5358e85857286d9c2ec6a026a968
git cat-file -p e6cd51e852b03986a75de394a936ceb9297108bd
7.merge
创建一个test分支,形成一个提交 44504044189cf4ef4567aabddb7c17e50ba18383
切回master分支 ,形成一个提交 d12dbded72e47d539baf66b393194597056fa609
查看最后一个commit object的内容
发现其有两个parent44504044189cf4ef4567aabddb7c17e50ba18383d12dbded72e47d539baf66b393194597056fa609
即之前形成的两个提交