git对象是什么
git中有个叫做.git/objects的文件夹被称为git的数据库或者对象库,里面存在着好多以两位十六进制的目录如29,目录中会有一些文件,文件名是01e239516f4f92d0612c892e3cafc20d580c75。
那么这些奇怪的文件是什么呢?
这是git中的对象都是以文件存储,有四种基本类型blob,tree,commit,tag。
我们通过cat .git/objects/29/ 1e2d038385561d391d6930842e3d21e5815a7b试图查看文件内容,不好!是一群乱码,那有什么方法可以查看这个文件呢?
我们通过git cat-file -t 291e2d0查看可以这个文件对应的对象类型是commit,git cat-file commit 291e2d0可以看到:
![5cc86a8ec08a782013d7d7a32acd8e19.png](https://i-blog.csdnimg.cn/blog_migrate/4491c0cf0b09199946dc182e082b0089.png)
tree代表这个提交对象对应的目录树,后面是它的哈希值。
parent代表这个提交对象对应的父提交,后面是它的哈希值(父提交可能有俩个:通过合并)。
author和committer是作者和提交者,空一行,后面是你的提交信息。
因为git程序可以快速通过哈希索引到tree和parent,这个哈希就像c的指针一样灵活,我们同样使用git cat-file -p 191a0c665b4014797d08340ae38ff662e604e516我们就可以快速查看对应目录tree对象的内容:
![7b9031eea2c7ef591cdff5e6a532a7fe.png](https://i-blog.csdnimg.cn/blog_migrate/2664e7e4f91c54e9ead08a6a27dbf37d.png)
里面每一列分别是目录树中每一项的权限,类型,哈希值,文件名。
这些tree类型的对象是一些子树,它们都拥有它们自己的目录树,里面同样是一些文件和目录。
总算注意到了blob类型的对象,blob本意墨水,这里指代的就是单一的文件对象。我们再次使用git cat-file -p 22ae76e :可以看到这个一个真实的普通html文件内容。
![c51891b1b9664335e8efa857553732dd.png](https://i-blog.csdnimg.cn/blog_migrate/f1e7100641d4439d6d4c395fa4f507b1.png)
当然还有tag对象:通过git tag -a v1.4 -m "my version 1.4"生成,在.git/refs/tags/v1.4可以看到一串哈希:
254571375f2a56e67ce188b6116ea9bdd77cbdbc
![74f909876e97b5b177bdd77faf4d31c8.png](https://i-blog.csdnimg.cn/blog_migrate/afc2612f7c9fead3b1c1a8c5c387a66b.png)
可以发现这个tag对象存储的内容是:
它所指向的提交对象的哈希,对象类型,标签名,标记的人,标记信息。
再git cat-file -p 0d6b00,就是我们标记时的commit提交。
我们可以推测:git底层靠着文件内容生成哈希,再将文件内容和类型信息压缩存入到对应哈希的.git/objects/xx/xxxxxxx...的位置,接着git再生成目录树存储各个blob对象和子树的哈希和信息,接着提交的时候再记录最顶端树的哈希,和当前HEAD提交的哈希,我们整条git仿佛通过哈希联系在一起,所以linus当初说做git是为了实现一个用户的文件系统。
通过哈希(指针),数据库存放的四种对象(类),HEAD(引用),git能够在客户端实现高效的版本控制。
文章转自:小组19级成员--胡哲宁
![2c1a6b31085f476a6e52295d381078aa.png](https://i-blog.csdnimg.cn/blog_migrate/3c4480352b4abc29fd102b359570a6a2.jpeg)