之前提到当存储数据内容时,会在objects文件夹下存储一个git对象。我们花些时间来看看 Git 是如何存储对象的。你将看来如何通过 Ruby 脚本语言存储一个 blob 对象 ,有必要了解一下对象是如何被存储的。以git设计哲学中的test1.txt为例分析blob对象如何被计算校验和?如何被存储?是否和直接调用git命令的结果一致?

sha-1校验和计算

我们需要验证通过ruby计算出来的检验和与这个一致。

为了验证,新建一个git仓库

$ mkdir blobtest
$ cd blobtest

 $ git init
 Initialized empty Git repository in /Users/lyc/Desktop/tg/.git/

同样新建一个文件test1.txt,内容为test1,并把它加入暂存区
$ echo test1 > test1.txt
$ git add test1.txt

gitt使用'blob ' + len(content) + '\0' + content作为文件内容
blob表示对象类型为blob类型,

len表示内容的长度

\0为空字节

其中'blob ' + len(content) + '\0' 来组成一个header,然后再将这个header与真正的内容拼接起来,并计算拼接后的新内容的 SHA-1 校验和。

使用 irb 命令进入 Ruby 交互式模式:

$ irb
irb(main)::> content = "test1\n"
=> "test1\n"
irb(main)::> header = "blob #{content.length}\0"
=> "blob 6\u0000"
irb(main)::> store = header + content
=> "blob 6\u0000test1\n"
irb(main)::> require 'digest/sha1'
=> true
irb(main)::> sha1 = Digest::SHA1.hexdigest(store)
=> "a5bce3fd2565d8f458555a0c6f42d0504a848bd5"

可见计算出来的校验后与刚开始设定的校验和是一致的。

git对象存储

git设计哲学中我们了解到test1.txt被git add命令添加到git仓库后,存储的路径如下

.git/
|--index
|--objects
| |--a5
| | |-- bce3fd2565d8f458555a0c6f42d0504a848bd5

我们通过ruby命令来对数据进行压缩然后存储,看看会发生什么。

Git 用 zlib 对数据内容进行压缩,在 Ruby 中可以用 zlib 库来实现。

irb(main)::> require 'zlib'
=> true
irb(main)::> zlib_content = Zlib::Deflate.deflate(store)
=> "x\x9CK\xCA\xC9OR0c(I-.1\xE4\x02\x00\x1D\xC5\x03\xF1"

最后将用 zlib 压缩后的内容写入磁盘。

git的存储的规则是:sha1值的前2位作为文件夹名,后38位作为文件名

irb(main)::> path = '.git/objects/' + sha1[,] + '/' + sha1[,]
=> ".git/objects/a5/bce3fd2565d8f458555a0c6f42d0504a848bd5"
irb(main)::> require 'fileutils'
=> true
irb(main)::> FileUtils.mkdir_p(File.dirname(path))
=> [".git/objects/a5"]
irb(main)::> File.open(path, 'w') { |f| f.write zlib_content }
=>

把它存储在.git的objects目录下

.git/
|--index
|--objects
| |--a5
| | |-- bce3fd2565d8f458555a0c6f42d0504a848bd5

这样就完成了一次blob对象的创建。

退出irb后,用git命令验证下创建对象的内容

$ git cat-file -p a5bce3fd2565d8f458555a0c6f42d0504a848bd5
test1

结果与test1.txt的内容一致。

执行git st命令查看下状态,

$ git st
On branch master Initial commit Untracked files:
(use "git add <file>..." to include in what will be committed) test1.txt

发现是untracked

再用git add命令

$ git st
On branch master Initial commit Changes to be committed:
(use "git rm --cached <file>..." to unstage) new file: test1.txt

再看.git/objects目录下,目录没变,还是

.git/
|--index
|--objects
| |--a5
| | |-- bce3fd2565d8f458555a0c6f42d0504a848bd5

结论:Git 以对象类型为起始内容构造一个文件头,本例中是一个 blob。然后添加一个空格,接着是数据内容的长度,最后是一个空字节 (null byte),接着用这个文件头和真正的内容拼接起来(不是文件名)计算校验和,然后用zlib对数据进行压缩,按照SHA-1 值的头两个字符作为子目录名称,剩余 38 个字符作为文件名保存压缩后的数据。这样就把一个文件存储到了git仓库中。

出处

git对象存储的更多相关文章

  1. 腾讯云 COS 对象存储使用

    目前使用腾讯云的对象存储cos服务,将本地的文件同步到cos中,看了腾讯云的用户文档,发现使用COS Migration 工具还是挺适合的. 原因 因为服务器已经安装有java环境,而cos的几个用户 ...

  2. [转帖]Git数据存储的原理浅析

    Git数据存储的原理浅析 https://segmentfault.com/a/1190000016320008   写作背景 进来在闲暇的时间里在看一些关系P2P网络的拓扑发现的内容,重点关注了Ma ...

  3. openstack-r版(rocky)搭建基于centos7.4 的openstack swift对象存储服务 三

    openstack-r版(rocky)搭建基于centos7.4 的openstack swift对象存储服务 一 openstack-r版(rocky)搭建基于centos7.4 的openstac ...

  4. openstack-r版(rocky)搭建基于centos7.4 的openstack swift对象存储服务 二

    openstack-r版(rocky)搭建基于centos7.4 的openstack swift对象存储服务 一 openstack-r版(rocky)搭建基于centos7.4 的openstac ...

  5. openstack-r版(rocky)搭建基于centos7.4 的openstack swift对象存储服务 一

    openstack-r版(rocky)搭建基于centos7.4 的openstack swift对象存储服务 一 openstack-r版(rocky)搭建基于centos7.4 的openstac ...

  6. swift(Object Storage对象存储服务)(单节点)

    # 在部署对象存储服务(swift)之前,你的环境必须包含身份验证服务(keystone); # keystone需要MySQL数据库,Rabbitmq服务,Memcached服务; # 内存:4G ...

  7. 对象存储 - Swift 原理 及 Swift+keystone+dashboard 架构搭建

    1. 原理介绍 Swift 架构.原理及功能: http://www.cnblogs.com/sammyliu/p/4955241.html 总结的很详细也很全面,受益匪浅,感谢分享. 2. keys ...

  8. Git 内部原理之 Git 对象哈希

    在上一篇文章中,将了数据对象.树对象和提交对象三种Git对象,每种对象会计算出一个hash值.那么,Git是如何计算出Git对象的hash值?本文的内容就是来解答这个问题. Git对象的hash方法 ...

  9. 七牛云对象存储kodo使用体验

    在这里,我使用了七牛云的对象存储Kodo,和阿里云的OSS,还有腾讯云的COS是同样的产品 oss相关术语 包依赖关系解决 unrecognized import path "golang. ...

随机推荐

  1. bzoj2749

    根绝欧拉函数的计算式,欧拉函数次方每次就是不断把2消掉,并把其他质因子不断变出2,最终弄成1显然我们先预处理每个数会被弄出多少个2出来,次方=弄出来的2的总数-[一开始是否有2](因为一开始没2的话是 ...

  2. 深入浅MFC

    视图类CView 在MFC"文档/视图"架构中,CView类是所有视图类的基类,它提供了用户自定义视图类的公共接口.在"文档/视图"架构中,文档负责管理和维护数 ...

  3. Chrome 控制台console的用法(学了之后对于调试js可是大大有用的哦)

    大家都有用过各种类型的浏览器,每种浏览器都有自己的特色,本人拙见,在我用过的浏览器当中,我是最喜欢Chrome的,因为它对于调试脚本及前端设计调试都有它比其它浏览器有过之而无不及的地方.可能大家对co ...

  4. LoadRunner调用Java程序—性能测试

    为了充分利用LoadRunner的场景控制和分析器,帮助我们更好地控制脚本加载过程,从而展现更直观有效的场景分析图表.本次将重点讨论LoadRunner如何调用Java测试代码,完成压力测试. 通常我 ...

  5. 关于mysql的error-based injection payload

    今天用sqlmap扫一个网站,想得到一个表的所有列名,注意到sqlmap用到的一个error-based payload的: 1 AND (SELECT 3174 FROM(SELECT COUNT( ...

  6. POJ 1661 Help Jimmy DP

    思路:Jimmy 跳到一块板上后,可以有两种选择,向左走或向右走.走到左端和走到右端所需的时间,容易算出. n如果我们能知道,以左端为起点到达地面的最短时间,和以右端为起点到达地面的最短时间,那么向左 ...

  7. Python安装、配置

    1.Python简介:Python在Linux.windows.Mac os等操作系统下都有相应的版本,不管在什么操作系统下,它都能够正常工作.除非使用平台相关功能,或特定平台的程序库,否则可以跨平台 ...

  8. POJ2407–Relatives(欧拉函数)

    题目大意 给定一个正整数n,要求你求出所有小于n的正整数当中与n互质的数的个数 题解 欧拉函数模板题~~~因为n过大~~~所以直接用公式求 代码: #include<iostream> # ...

  9. HDU5627--Clarke and MST (bfs+位运算)

    http://www.cnblogs.com/wenruo/p/5188495.html Clarke and MST Time Limit: 2000/1000 MS (Java/Others) M ...

  10. javascript获取元素的计算样式

    使用css控制页面有4种方式,分别为行内样式(内联样式).内嵌式.链接式.导入式. 行内样式(内联样式)即写在html标签中的style属性中,如<div style="width:1 ...