Git 数据是怎么存储的
git 的数据存储数据结构是键值类型,git中底层生成了4中数据的对象
- commit:commit 对象指向一个 tree 对象,并且带有相关的描述信息.
- tree: 可以看作一个目录
- blob: 通常用来存储文件的内容
- tag:tag 对象包括一个对象名(SHA1签名)、对象类型、标签名、标签创建人的名字(“tagger”), 还有一条可能包含有签名(signature)的消息
上图出自 sixgo-Git数据存储的原理浅析
举例提交
> git commit -m ‘chore: LAO‘ [master (root-commit) 4b9fc1a] chore: LAO 2 files changed, 57 insertions(+) create mode 100644 index.html create mode 100644 test.js > git log commit 4b9fc1a52e74ed4e408c4994296a1f960533f48b (HEAD -> master) Author: Ever-lose <> Date: Mon May 4 19:28:20 2020 +0800 chore: LAO
使用 git cat-file
# 获取此 commitid 的类型,是 commit > git cat-file -t 4b9fc1a52e74ed4e408c4994296a1f960533f48b commit # 获取 tree > git cat-file -p 4b9fc1a52e74ed4e408c4994296a1f960533f48b tree 5937ab7ef5b6aaf4aad3ad4b09bfef7b97ee6e39 author Ever-lose <> 1588591700 +0800 committer Ever-lose <> 1588591700 +0800 chore: LAO # 获取 blob > git cat-file -p 5937ab7ef5b6aaf4aad3ad4b09bfef7b97ee6e39 100644 blob 0f7b3babfbcec4778ef50337115faf87e67fc682 index.html 100644 blob 39a772dd49196db8bfffb50a58bd10bac3dcb4ab test.js # 获取 index.html 里的 blob 内容 > git cat-file -p 0f7b3babfbcec4778ef50337115faf87e67fc682 <!DOCTYPE html> <html lang="en"> <head> ... 省略
由此可知 git 存储是存储一整个文件的。并且能注意到项目目录的 .git\objects
下有个目录叫 4b
,里面有个叫 9fc1a52e74ed4e408c4994296a1f960533f48b
的文件,其实 4b
取自 commitId 里前两个字符,而 9fc1a52e74ed4e408c4994296a1f960533f48b
自然就是 commitId 里剩余的 38 个字符了。文件是二进制的,打开也看不明白。
第二次提交,笔者就修改了 index.html 里的第一行
> git commit -m ‘chore: 第二次提交‘ [master bd07fbb] chore: 第二次提交 1 file changed, 1 insertion(+) # 查看这两次提交 > git log --pretty=oneline bd07fbb7f181f868191862e542da1636109e4e46 (HEAD -> master) chore: 第二次提交 4b9fc1a52e74ed4e408c4994296a1f960533f48b chore: LAO # 获取 tree,注意下面 parent 是第一个 commitId > git cat-file -p bd07fbb7f181f868191862e542da1636109e4e46 tree 2df4d0cfd56341eeecb705a6c5c3eaebb66d4c63 parent 4b9fc1a52e74ed4e408c4994296a1f960533f48b author Ever-lose <> 1588592528 +0800 committer Ever-lose <> 1588592528 +0800 chore: 第二次提交 # 获取 blob > git cat-file -p 2df4d0cfd56341eeecb705a6c5c3eaebb66d4c63 100644 blob 114653874c6ed19c24c15f71532199aece94799d index.html 100644 blob 39a772dd49196db8bfffb50a58bd10bac3dcb4ab test.js # 查看 index.html 的 blob 对象,下文的 <!-- 测试提交 --> 就是修改的内容 > git cat-file -p 114653874c6ed19c24c15f71532199aece94799d <!-- 测试提交 --> <!DOCTYPE html> <html lang="en">
结论
git 的数据存储数据结构是键值类型,git中底层生成了4中数据的对象。
每个 commit,git 都要存储所有的文件内容,所以这样会导致存储的数据量很大。所以检出时使用 git clone xxxrepo --depth 1
会有奇效。
因为数据量大,git 自然不会采用明文传递文件了,所以 blob 内容是采用 zlib 进行数据压缩了的,只是我们用 git cat-file 看不出罢了。
参考
相关推荐
formula 2020-11-12
huhongfei 2020-11-05
乾坤一碼農 2020-10-27
liumengyanysu 2020-10-22
E哥的aws认证攻略 2020-10-15
tianyafengxin 2020-10-08
guying 2020-10-05
好脑筋不如烂笔头 2020-09-17
nebulali 2020-09-11
佛系程序员J 2020-09-15
fenggit 2020-09-15
JustHaveTry 2020-09-11
兄dei努力赚钱吧 2020-09-06
IngeniousIT 2020-08-25
liumengyanysu 2020-08-17
guying 2020-08-16