前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Git 对象存储结构分析

Git 对象存储结构分析

原创
作者头像
囚兔
修改2018-04-22 13:07:25
3.1K2
修改2018-04-22 13:07:25
举报
文章被收录于专栏:IT杂记

1. 前言

Git 对象有:blob (数据块), tree (目录树), commit (提交), tag (标签)。

本文通过一个示例,以blob为例来讨论对象的存储结构。示例采用的git版本为2.17

2. 实践讨论

2.1. 生成Blob对象文件

首先创建一个测试git仓库

代码语言:txt
复制
$ mkdir hello
$ cd hello
$ git init

然后通过创建一个文件 test,test的内容为 "hello", 可以看到test文件的字节长度为6, 是因为创建文件的时候自动在行末加上了换行符\n。对文件其执行 git add , 可以看到在.git/objects目录下面生成了一个子目录ce,ce目录下面有个文件013625030ba8dba906f756967f9e9ca394464a。

代码语言:txt
复制
$ echo "hello" > test
$ du -b test
6       test
$ git add test
$ find .git/objects/ -type f
.git/objects/ce/013625030ba8dba906f756967f9e9ca394464a

该文件即为git为 test 文件数据内容生成的blob对象文件,该对象的SHA值为ce013625030ba8dba906f756967f9e9ca394464a.

至此,产生两个问题:

  1. 对象文件的数据结构是什么样的 ?
  2. 对象的SHA值又是如何生成的 ?

2.2. 对象数据结构及SHA值

根据 Git-Internals-Git-Objects 文中的描述:

首先,对象文件数据结构如下图:

git-object-storage.png
git-object-storage.png
  • content: 表示数据内容
  • head: 对象头部信息
    • object type:对象类型,可选值为 blob, tree, commit
    • whitespace: 一个空格字符
    • content byte size:数据内容的字节数字符串
    • NUL:空字符,ASCII码值为0

然后, 对象的SHA值就是对上面这个数据结构执行SHA1 hash摘要算法得到的。

2.3. 动手验证

根据2.2中的规则来编码对2.1中的test文件内容生成一个SHA值,看是否和git生成的SHA值一致?

代码语言:txt
复制
    // object content
    String content = "hello\n";
    byte[] contentBytes = content.getBytes();

    ByteBuffer buf = ByteBuffer.allocate(1024);


    buf.put("blob".getBytes()); // object type
    buf.put((byte) ' ');        // whitespace
    buf.put(Integer.toString(contentBytes.length).getBytes());  // content byte size numeric string
    buf.put((byte) 0);          // NUL
    buf.put(contentBytes);      // content

    buf.flip();

    // whole object bytes
    byte[] objectBytes = new byte[buf.remaining()];
    buf.get(objectBytes);

    // Execute SHA1 hash digest
    MessageDigest md = MessageDigest.getInstance("SHA1");
    byte[] shaBytes = md.digest(objectBytes);

    // Show in hex
    String shaHex = Hex.encodeHexString(shaBytes);
    System.out.println(shaHex);

上述代码输出:ce013625030ba8dba906f756967f9e9ca394464a

和 2.1 中git生成的SHA值一致,2.2 中数据结构和SHA值的生成得到验证。

2.4. 对象压缩

根据 Git-Internals-Git-Objects 可知git 对象文件是经过Zlib::Deflate.deflate 压缩存储的。

代码语言:txt
复制
$ cat .git/objects/ae/a941d707291bf3f2103c096479b068f7bed4f8
x☺K
cat: write error: Input/output error

可以看到通过cat命令是无法直接输出内容的。

代码语言:txt
复制
        InputStream is = new InflaterInputStream(new FileInputStream(
                ".git\\objects\\ce\\013625030ba8dba906f756967f9e9ca394464a"));

        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        int b = 0;
        while ((b = is.read()) != -1) {
            baos.write(b);
        }

        byte[] res = baos.toByteArray();
        System.out.println(new String(res));

        is.close();
        baos.close();

通过如上代码可输出对象的数据结构:

代码语言:txt
复制
blob 6hello

注其中包括不可见字符NUL和换行符。

通过git cat-file命令可以直接查看对象的数据内容:

代码语言:txt
复制
$ git cat-file -p ce013625030ba8dba906f756967f9e9ca394464a
hello

3. 总结

  1. 对象数据结构为:
git-object-storage.png
git-object-storage.png
  1. 对象SHA值为对( 1. 对象数据结构)执行SHA1消息摘要算法生成;
  2. 对象存储结构为:对(1. 对象数据结构)进行deflate压缩后存储;

4. 参考资料

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 前言
  • 2. 实践讨论
    • 2.1. 生成Blob对象文件
      • 2.2. 对象数据结构及SHA值
        • 2.3. 动手验证
          • 2.4. 对象压缩
          • 3. 总结
          • 4. 参考资料
          相关产品与服务
          对象存储
          对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档