• 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 <ever-lose@foxmail.com>
    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 <ever-lose@foxmail.com> 1588591700 +0800
    committer Ever-lose <ever-lose@foxmail.com> 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 存储是存储一整个文件的。并且能注意到项目目录的 .gitobjects 下有个目录叫 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 <ever-lose@foxmail.com> 1588592528 +0800
    committer Ever-lose <ever-lose@foxmail.com> 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 看不出罢了。

    参考

    sixgo-Git数据存储的原理浅析

  • 相关阅读:
    Java版剑指offer
    使用轻量应用服务器部署Docsify在线文档平台
    阿里云弹性计算年度关键词:强劲、突破、开放
    征文投稿丨使用轻量应用服务器搭建扫码测试项目
    投稿有奖丨阿里云云服务器ECS开发实践征文活动
    GRAPH CONVOLUTIONAL NETWORK WITH SEQUENTIAL ATTENTION FOR GOALORIENTED DIALOGUE SYSTEMS
    Learning Latent Graph Representations for Relational VQA
    Host–Parasite(主从关系): Graph LSTMinLSTM for Group Activity Recognition
    Issues in multiparty dialogues(科普性质)
    Conversation Modeling on Reddit Using a GraphStructured LSTM
  • 原文地址:https://www.cnblogs.com/everlose/p/12828020.html
Copyright © 2020-2023  润新知