美文网首页Git
git的文件系统与底层原理 (1)

git的文件系统与底层原理 (1)

作者: traxes | 来源:发表于2018-05-05 14:05 被阅读5次

    由于工作中使用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的文件系统与底层原理 (1)

        本文链接:https://www.haomeiwen.com/subject/tirdlftx.html