git的文件系统与底层原理

由于工作中使用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的数据存储的基本方式。主要步骤:

  1. 使用SHA-1算法根据其原始内容和头信息(头信息格式"blob #{content.length}\0")生成唯一的40位校验和。
  2. 以校验和前两位创建文件夹、校验和后38位作为文件名。
  3. 对拼接后的内容压缩后存储。

下面是创建文件,修改文件,恢复文件的相关过程。

  • 重新创建一个仓库并创建一个文件
$ 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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Git 基础 基本原理 客户端并不是只提取最新版本的文件快照,而是把代码仓库完整的镜像下来。这样一来,任何一处协同...
    __silhouette阅读 15,947评论 5 147
  • Git 命令行学习笔记 Git 基础 基本原理 客户端并不是只提取最新版本的文件快照,而是把代码仓库完整的镜像下来...
    sunnyghx阅读 3,951评论 0 11
  • 一、电脑本地初始化一个仓库 1. git init: 初始化一个电脑上本地仓库 终端进入项目目录,输入: 该命令将...
    dragon_li阅读 2,999评论 1 4
  • 【2016.09.15】 今天中秋节了。 我在大学的最后一个中秋,还是没有回家过。 虽然还是一个人,今年的中秋还不...
    真的以为阅读 258评论 0 0
  • 人与人之间形成差距的最大原因是什么? 出生不好? 专业不好? 运气不好? 社会不公平? 太穷了? 我的答案是:求精...
    人随心动2017阅读 511评论 0 3