git技术实现分析
2017-07-30 19:48
197 查看
Git 是一套内容寻址文件系统。从内部实现来看,Git 是简单的 key-value 数据存储。它允许插入任意类型的内容,并通过hash-object返回一个键值,通过该键值可以在任何时候再取出该内容。它会将数据保存在
Git通过上层命令提交后生成几个对象,这些对象组成了git文件的数据结构。
Git中有四种基本对象类型,组成了Git更高级的数据结构。
1.tag对象:tag用于给某个上述类型的对象指配一个便于开发者记忆的名字, 通常用于某次commit。例如git commit -m "tag".
2.tree对象:每个tree代表了一个目录的信息,包含了此目录下的blobs,子目录(对应于子trees),文件名、路径等元数据。因此,对于有子目录的目录,git相当于存储了嵌套的trees。
3.blob对象:每个blob代表一个(版本的)文件,blob只包含文件的数据,而忽略文件的其他元数据,如名字、路径、格式等。
4.commit对象:每个commit记录了提交一个更新的所有元数据,如指向的tree,父commit,作者、提交者、提交日期、提交日志等。每次提交都指向一个tree对象,记录了当次提交时的目录信息。一个commit可以有多个(至少一个)父commits。
详细内容可以参考《pro git》。
下面详细介绍一下blob对象如何被计算校验和,如何被存储。
git使用'blob ' + len(content) + '\0' + content作为文件内容
blob表示对象类型为blob类型,
len表示内容的长度
\0为空字节
其中'blob ' + len(content) + '\0' 来组成一个header,然后再将这个header与真正的内容content拼接起来,并计算拼接后的新内容的 SHA-1 校验和。Git 用 zlib 对数据内容进行压缩,最后将用 zlib 压缩后的内容写入磁盘。注意写入磁盘的不是文件的具体内容而是由header和content连接起来的内容通过SHA-1哈希出来的40位的摘要。取摘要的前两位作为目录,后面38位作为内容存储在磁盘上。
所以Git 以对象类型为起始内容构造一个文件头。然后添加一个空格,接着是数据内容的长度,最后是一个空字节 (null byte),接着用这个文件头和真正的内容拼接起来(不是文件名)计算校验和,然后用zlib对数据进行压缩,按照SHA-1
值的头两个字符作为子目录名称,剩余 38 个字符作为文件名保存压缩后的数据。这样就把一个文件存储到了git仓库中。
估计也会有小伙伴和我一样好奇既然磁盘上存的是一个哈希值,那么具体的文件内容存在哪里了?其实git依赖于一个键/值对的数据库,这个hash值就是存储在数据库中的键,具体内容才是值。通过命令:git cat-file
-p hashcode-key 可以取出文件内容。
.git目录并返回表示这些数据的键值。
Git通过上层命令提交后生成几个对象,这些对象组成了git文件的数据结构。
Git中有四种基本对象类型,组成了Git更高级的数据结构。
1.tag对象:tag用于给某个上述类型的对象指配一个便于开发者记忆的名字, 通常用于某次commit。例如git commit -m "tag".
2.tree对象:每个tree代表了一个目录的信息,包含了此目录下的blobs,子目录(对应于子trees),文件名、路径等元数据。因此,对于有子目录的目录,git相当于存储了嵌套的trees。
3.blob对象:每个blob代表一个(版本的)文件,blob只包含文件的数据,而忽略文件的其他元数据,如名字、路径、格式等。
4.commit对象:每个commit记录了提交一个更新的所有元数据,如指向的tree,父commit,作者、提交者、提交日期、提交日志等。每次提交都指向一个tree对象,记录了当次提交时的目录信息。一个commit可以有多个(至少一个)父commits。
详细内容可以参考《pro git》。
下面详细介绍一下blob对象如何被计算校验和,如何被存储。
git使用'blob ' + len(content) + '\0' + content作为文件内容
blob表示对象类型为blob类型,
len表示内容的长度
\0为空字节
其中'blob ' + len(content) + '\0' 来组成一个header,然后再将这个header与真正的内容content拼接起来,并计算拼接后的新内容的 SHA-1 校验和。Git 用 zlib 对数据内容进行压缩,最后将用 zlib 压缩后的内容写入磁盘。注意写入磁盘的不是文件的具体内容而是由header和content连接起来的内容通过SHA-1哈希出来的40位的摘要。取摘要的前两位作为目录,后面38位作为内容存储在磁盘上。
所以Git 以对象类型为起始内容构造一个文件头。然后添加一个空格,接着是数据内容的长度,最后是一个空字节 (null byte),接着用这个文件头和真正的内容拼接起来(不是文件名)计算校验和,然后用zlib对数据进行压缩,按照SHA-1
值的头两个字符作为子目录名称,剩余 38 个字符作为文件名保存压缩后的数据。这样就把一个文件存储到了git仓库中。
估计也会有小伙伴和我一样好奇既然磁盘上存的是一个哈希值,那么具体的文件内容存在哪里了?其实git依赖于一个键/值对的数据库,这个hash值就是存储在数据库中的键,具体内容才是值。通过命令:git cat-file
-p hashcode-key 可以取出文件内容。
相关文章推荐
- 阿里云PolarDB及其共享存储PolarFS技术实现分析(下)
- Linux 实时技术与典型实现分析, 第 1 部分: 介绍
- 网闸——物理隔离功能及实现技术分析
- 网易新闻客户端iOS版本中新闻详情页(UIWebView)技术实现的分析探讨
- HTTP Live Streaming直播(iOS直播)技术分析与实现
- Python实现一个Git日志统计分析的小工具
- HTTP Live Streaming直播(iOS直播)技术分析与实现
- MySQL中连接池的技术实现和分析
- HTTP Live Streaming直播(iOS直播)技术分析与实现
- ZigBee技术的硬件实现模式分析
- 全面分析IDC双线路实现技术方案
- HTTP Live Streaming直播(iOS直播)技术分析与实现
- 5-爬虫的运行原理及实现技术分析
- HTTP Live Streaming直播(iOS直播)技术分析与实现
- HTTP Live Streaming直播(iOS直播)技术分析与实现
- HTTP Live Streaming直播(iOS直播)技术分析与实现
- jquery lazyload延迟加载技术的实现原理分析
- HTTP Live Streaming直播(iOS直播)技术分析与实现
- 阿里云PolarDB及其共享存储PolarFS技术实现分析(上)
- 翻翻git之---自己定义邮件发送buttonSendButton(流程分析,实现思路能够学习下)