由于工作中使用git作为版本管理,之前对git的了解不多,特别是底层方面的原理方面的知识。为了能更好的使用git,有必要学习并梳理下相关知识。
步入正题:
git的文件结构
执行git init 初始化后,会在.git文件夹下会创建多个目录,每个文件夹功能划分的很清晰。
git目录结构.png
git的存储方式
Git 是一套内容寻址文件系统.通过键值对的方式存储和查找。
下面操作一遍,直观的看到整个过程,以便理解。
- 首先,创建一个内容对象
$ echo "小明的文件" | git hash-object -w --stdin
5c98f8a9221e5336f68c7575cd238b48875137c6
命令/参数 | 说明 |
---|---|
echo | 将字符串输出到终端 |
git hash-object | 创建一个blob(二进制大对象), 可指定其他类型,不一定是blob。 |
--stdin | 从标准终端中读取输入,代替从文件读取, 这里读取的是由echo命令输出到终端的字符串。 |
-w | 把blob对象写入数据库 |
参考:https://git-scm.com/docs/git-hash-object
- 查看刚才存储的数据
$ find .git/objects -type f
.git/objects/5c/98f8a9221e5336f68c7575cd238b48875137c6
命令/参数 | 说明 |
---|---|
find | 查找目录下文件 |
-type f | 指定查类型为普通文件 |
参考:http://man.linuxde.net/find
可以见到文件名称为数字和字母组成的字符串。这个是根据文件内容和头信息(Header),通过SHA-1算法计算得出的40位十六进制校验和。
校验和 | 5c98f8a9221e5336f68c7575cd238b48875137c6 |
存储路径 | 5c/98f8a9221e5336f68c7575cd238b48875137c6 以校验和前两位作为子路径创建文件夹, 以校验和后38位作为文件名生成文件。 |
SHA-1是一种加密哈希函数(cryptographic hash function)。SHA-1将文件中的内容通过其hash算法生成一个160bit的报文摘要,即40个十六进制数字(每个十六进制数字占4位)。它几乎可以保证,如果两个文件的SHA-1值是相同的,那么它们确是完全相同的内容(类似于生活中的指纹识别);SHA-1主要有两种用途,一个是加密,一个是数据完整性校验。Linux kernel开创者和Git的开发者——Linus说,Git使用了SHA-1并非是为了安全性,而是为了数据的完整性。理论上SHA-1会在2^51攻击下实现哈希碰撞,所以也不是完全的安全。
- 通过校验和作为键值 解读文件
$ git cat-file -p 5c98f8a9221e5336f68c7575cd238b48875137c6
小明的文件
命令/参数 | 说明 |
---|---|
git cat-file | 读取对象信息 |
-p | 根据对象的类型打印其信息 |
参考:https://git-scm.com/docs/git-cat-file
模拟bolb对象存储流程
bolb存储流程图.png
以上,说明了git的数据存储的基本方式。主要步骤:
- 使用SHA-1算法根据其原始内容和头信息(头信息格式"blob #{content.length}\0")生成唯一的40位校验和。
- 以校验和前两位创建文件夹、校验和后38位作为文件名。
- 对拼接后的内容压缩后存储。
下面是创建文件,修改文件,恢复文件的相关过程。
- 重新创建一个仓库并创建一个文件
$ echo '小明该吃午饭了' > test.txt
$ git hash-object -w test.txt
efbd70f46da0d1852de88c58aebc86616beecdaf
- 修改文件再保存
$ echo "小明打算去吃个泡面" > test.txt
$ git hash-object -w test.txt
26aab56c7d1f9bd962b28f78ce61f021b221d317
- 查看已保存的内容
$ find .git/objects -type f
.git/objects/26/aab56c7d1f9bd962b28f78ce61f021b221d317
.git/objects/ef/bd70f46da0d1852de88c58aebc86616beecdaf
- 恢复到第一个版本
$ git cat-file -p efbd70f46da0d1852de88c58aebc86616beecdaf > .git/test.txt
$ cat .git/test.txt
小明该吃午饭了
git会记录每个版本的修改,根据校验和可恢复到相应的版本。
小结:这个过程中包括文件创建、文件修改、文件恢复,跟我们平时工作中使用的高级命令功能很相似。git会把整个过程转化为底层操作,同时对用户透明。
相关引用参考:
http://smilejay.com/2012/08/git-commit-sha-1/
https://git-scm.com/book/zh/v1/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-Git-%E5%AF%B9%E8%B1%A1
网友评论