文档章节

Git 对象存储结构分析

囚兔
 囚兔
发布于 2018/04/21 22:57
字数 758
阅读 334
收藏 6
Git

1. 前言

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

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

2. 实践讨论

2.1. 生成Blob对象文件

首先创建一个测试git仓库

$ mkdir hello
$ cd hello
$ git init

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

$ 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 文中的描述:

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

输入图片说明

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

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

2.3. 动手验证

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

    // 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 压缩存储的。

$ cat .git/objects/ae/a941d707291bf3f2103c096479b068f7bed4f8
x☺K
cat: write error: Input/output error

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

        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();

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

blob 6hello

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

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

$ git cat-file -p ce013625030ba8dba906f756967f9e9ca394464a
hello

3. 总结

  1. 对象数据结构为:

输入图片说明

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

4. 参考资料

© 著作权归作者所有

共有 人打赏支持
囚兔

囚兔

粉丝 39
博文 86
码字总数 47164
作品 1
南京
程序员
私信 提问
加载中

评论(2)

再问
再问
Nice
红薯
红薯
赞!
Git 内部原理之 Git 对象存储

原文出处:彭金金 在Git内部原理之Git对象哈希中,讲解了Git对象hash的原理,接下来的这篇文章讲一讲Git对象如何存储。 原理 数据对象、树对象和提交对象都是存储在.git/objects目录下,目录...

彭金金
2018/06/24
0
0
使用 Libgit2 实现在数据库中存储 Git 仓库

Git有一个出名的定义明确的数据存储结构。在每一个Git仓库的.git目录下,你都可以找到下面几个目录:用于存储数据的objects目录,refs目录,用于分支以及标记指针等等。除此之外,Git仓库中所...

oschina
2014/02/26
2.7K
3
几张图让你彻底弄懂git工作流(三) ——git深入

前两篇文章分别说了git简史与git基础以及git分支,那么这篇文章开始简单描述一下git深入 Git深入 在 Git 中提交时,会保存一个提交(commit)对象,该对象包含一个指向暂存内容快照的指针,包...

Li_小点
2018/05/28
0
0
程序员必备技能之 Git 的体系结构与历史

作者 | Will Hay Jr. 译者 | 梁蕊 责编 | 屠敏 出品 | CSDN(ID:CSDNNews) 截至 2018 年,全球知名的 IT 技术问答网站 Stack Overflow 调查的 74000 开发人员中,将近 90% 的人表示更喜欢使...

CSDN资讯
01/12
0
0
Android开发工程师,新长征路上的14项技能

导读: 你曾渴望回到宋朝吗? 或者什么朝,反正就是男耕女织的古代。 哦,那时的首都在汴梁(开封),房价想必没有这么高,工作?无非就是给你把锄头,去,种地去。夕阳西下了,麦子垛后,你和...

半饱即好
2014/05/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

安装mysql8.0.11以及修改root密码、连接navicat for mysql。

安装mysql8.0.11以及修改root密码、连接navicat for mysql。   最近在学习node.js,少不得要跟数据库打交道,于是打算安装一个数据库软件,在mongedb和mysql之间选择了mysql。作为一个数据...

linjin200
11分钟前
1
0
前嗅ForeSpider教程:创建模板

今天,小编为大家带来的教程是:如何在前嗅ForeSpider中创建模板。主要内容有:模板的概念,模板的配置方式,模板的高级选项,具体内容如下: 一,模板的概念 模板列表的层级相当于网页跳转的...

forespider
13分钟前
1
0
OSChina 周三乱弹 —— 除了电脑,别人都很开心

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @小小编辑:推荐歌曲,《三亩水田》- 蚂蚁先生 《三亩水田》- 蚂蚁先生 手机党少年们想听歌,请使劲儿戳(这里) @uknow8692 :感谢失业,让我...

小小编辑
16分钟前
170
11
django数据库自动重连

简介 Django数据库连接超过wait_timeout导致连接丢失时自动重新连接数据库 https://github.com/zhanghaofei/django-db-reconnect 安装 pip install django_db_reconnect 注意仅支持pymysql...

张豪飞
20分钟前
0
0
PostMan 工具使用使用,以及不同请求对应的ContentType 的设置

https://www.jianshu.com/p/d230d27b44fe

kuchawyz
20分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部