Git的存储原理

目录
  • Git 设计原理
    • Git vs SVN
    • Git 存储模型
      • .git 目录结构
      • Git 基本数据对象
      • Git 包文件
      • Git 引用

Git 设计原理

概括的讲,Git 就是一个基于快照的内容寻址文件系统。 往下慢慢看。

Git vs SVN

Git 出现前,主流版本控制系统(SVN...)一般为基于增量(delta-based)的系统,如下图:

img

Git 则是基于快照(snapshot),即针对每一个被修改的文件生成一个快照,没被修改的则不再重新生成快照,如下图:

img

直觉上讲,似乎基于增量的方式要更好些?

毕竟针对被修改的文件,Git 生成的是完全的快照,而其他系统只是生成增量文件。没错,但是当需要回滚版本或者比对多个版本间的差异时,Git 只需要取出对应版本的快照文件进行对比即可,而基于增量的系统则需要从头开始一步步应用增量文件来回溯,Git 的速度优势就很明显了。

Git 存储模型

.git 目录结构

当用git init 或者 git clone 获取一个 git 仓库时,可以发现目录下有一个隐藏目录。git,它的基本结构类似如下:

├── COMMIT_EDITMSG 仓库最后一次commit的message
├── FETCH_HEAD  每个分支的最后一次commit的SHA1值
├── HEAD 记录了HEAD指针的指向位置
├── ORIG_HEAD 针对某些危险操作,该指针记录了上一次安全版本的HEAD指针的位置,方便回退
├── config git的相关配置
├── index 暂存区,索引文件
├── packed-refs 已经压缩的分支,记录了每个分支的最后一次commit的SHA1
├── logs/ 操作日志,包括本地远程的
├── objects/ 对象存储文件夹
|   ├── ... 文件夹名称根据object的SHA1值的前2个字符确定
|   ├── ...
|   ├── info/
|   ├── pack/ 压缩后的数据
└── refs/ 记录本地和远程的最后一次commit的SHA1值├── heads/ 分支引用├── remotes/ 远程地址└── tags/ 标签引用

这个目录下包含了 Git 所有信息,且都是用文件的形式存储,所以说 Git 是一个文件系统。

Git 基本数据对象

  • blob(二进制大对象):也就是前面说的基于快照存储的文件
  • tree:目录,代表了 blob 对象的集合
  • commit:提交,包含了 blob、tree 的集合
  • tag:标签对象(指 annotation 标签),还有一种轻量标签不记录创建标签人等额外信息,不需要再单独创建标签对象

上述 4 种数据对象均存储在。git/object/目录下,git 会对每一种数据对象计算哈希值来确定具体的存储路径,下面来举个例子。

> echo 'test content' | git hash-object -w --stdin
d670460b4b4aece5915caf5c68d12f560a9fe3e4 
//40位的SHA-1哈希值,前2位位目录名,其他38位为文件名,存储路径即.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
> git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4test content 
> git cat-file -p master^{tree} // 输出master最新提交包含内容
100644 blob a906cb2a4a904a152e80877d4088654daad0c859      README  
100644 blob 8f94139338f9404f26296befa88755fc2598c289      Rakefile  
040000 tree 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0      lib
// 包含了2个文件的修改和1个目录的修改
> git cat-file -p 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0
100644 blob 47c6340d6459e05787f644c2447d2595f5d3a54b      simplegit.rb    

git hash-object 命令可以用于计算文件的哈希值

-w 表示把将对象写入到 git 数据库中

--stdin 表示从标准输入读取内容

git cat-file 命令可以根据传入哈希值取出 git 存储的对象

-p 自动判断内容的类型

一次提交的数据结构可以用下图来概括:

img

Git 包文件

可能有的小伙伴通过上述方式在自己项目中尝试时,发现在。git/objects/下找不到对应文件,这是什么原因呢?

可能真的不是操作出了问题,而是 Git 进行了压缩操作。

Git 最初存储对象时使用的时"松散(loose)"对象格式,即保存在。git/objects/下。

但是,Git 会时不时(或者当你手动执行git gc 命令后)地将这些对象打包成一个称为“包文件(packfile)”的二进制文件(存储在。git/objects/pack),以节省空间和提高效率。

Git 引用

引用类似于指针,除了 HEAD 存储在。git/HEAD 以外,其他指针存储在。git/refs 目录下

  • 分支
  • HEAD:一种特殊的指针,用于指向目前所在的 commit,。git/HEAD 文件里存储的就是引用的 commit 的哈希值
  • 标签(轻量标签)

可以看出,所谓的引用只是一个记录了 commit 哈希值的文件,非常的轻量,这也是为什么分支/标签的创建、删除速度能这么快的原因。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/772714.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

运行一个jar包的过程

在Linux运作jar包在Linux系统中,一个Java Archive(JAR)文件是包含Java类文件、相关的元数据和资源(如文本、图片等)的压缩包,通常用于存储Java应用程序或库。要在Linux上运行一个JAR包,你可以按照以下步骤操作: 1、确保Java环境已安装: 在Linux系统中运行JAR文件之前,…

BUUCTF 2.rip

拿到题目首先运行一下我们可以看到在我第一次运行时我们发现他就是将我们输入的重新输出了一遍,我们可以猜测应该是gets函数输入,然后输出,那我们便可以测试第二次,我们输入一个超长字符串,发现程序崩溃了,我们可以猜测应该是程序没有对长度进行检测而导致的栈溢出,那么…

计组笔记第七章——输入输出系统

7.1.1 I/O系统和IO控制方式常见I/O设备: 鼠标、键盘;显示器、打印机;硬盘、光盘。 主机如何与I/0设备进行交互? I/O接口:又称I/O控制器、设备控制器,负责协调主机与外部设备之间的数据传输。 I/O接口与CPU之间靠总线连接,与外设之间靠USB连接线连接。 I/O接口多种多样,…

Raft协议深度解析:RocketMQ中基于DLedger的日志主从复制

本文所涉及的注释源码:bigcoder84/dledgerRaft 协议主要包含两个部分:Leader选举和日志复制。 前面我们在 Raft协议深度解析:RocketMQ中的自动Leader选举与故障转移 一文中已经详细介绍了DLedger如何实现Leader选举的,而本文主要聚焦于Leader选举完成后的日志复制的过程。 …

Android低功耗子系统的投票机制以及触发进入系统休眠的过程

从kernel角度看,系统是否进入休眠应该由内核来控制,因此Linux引入了 wakeup source以及autosleep机制关于wakeup source的介绍,请参考: Wakeup Source框架设计与实现 关于autosleep机制,请参考:autosleep框架设计与实现在内核中,使用wakeup source提供投票机制,让各个系…

Java SE 文件上传和文件下载的底层原理

1. Java SE 文件上传和文件下载的底层原理 @目录1. Java SE 文件上传和文件下载的底层原理2. 文件上传2.1 文件上传应用实例2.2 文件上传注意事项和细节3. 文件下载3.1 文件下载应用实例3.2 文件下载注意事项和细节4. 总结:5. 最后:2. 文件上传文件的上传和下载,是常见的功能…

使用Excel画出各类统计图(3)

本章会介绍如何画出箱线图 目录一、箱线图1.箱线图的作用2.箱线图的绘制与调整(1)画出箱线图(2)调整箱线图 一、箱线图 箱线图用于反映一组或多组连续型定量数据分布的中心位置和散布范围。 箱线图上需要体现出数据的某些特性,因此需要计算上四分位数、中位数、下四分位数…

Docker 和 k8s 学习

披个甲:偷的图灵学院的笔记 docker:https://note.youdao.com/ynoteshare/index.html?id=db5365c679b7d9129cbcfab5cb682d69&type=note&_time=1722071596141 k8s:https://note.youdao.com/ynoteshare/index.html?id=b2d5991b16e43cef9ac5071fbc516026&type=not…

帝国CMS如何设置是安全最优化的

帝国CMS如何设置是安全最优化的:(注:以下选项都是非必须设置,只是优化建议。)php配置文件php.ini设置:1、magic_quotes_gpc 设置为 On 魔术引用,此项建议开启。2、register_globals 设置为 Off PHP全局变量,此项建议关闭。3、display_errors 设置为 Off 不显示PHP错…

易优CMS内容页调用下载附件-模板代码使用说明{eyou:volist name=$eyou.field.file_list id=field} 附

{eyou:volist name="$eyou.field.file_list" id="field"}附件文件名:{$field.file_name}文件提取码:{$field.extract_code}服务器名称:{$field.server_name}文件大小:{$field.file_size}下载链接:{$field.file_url} {/eyou:volist}扫码添加技术【解决…

1251 - Client does not support authentication protocol requested by server; consider upgrading MySQL

错误记录: 1251 - Client does not support authentication protocol requested by server; consider upgrading MySQL client 错误原因: mysql8 之前的版本中加密规则是mysql_native_password,而在mysql8之后,加密规则是caching_sha2_password。 解决方案: 解决:①升级nav…

易优cms 安装常见问题汇总 Eyoucms快速入门

安装报错,请仔细核对数据库账号和密码答:请检查填写的数据库链接信息是否正确,此问题都是填写的数据库地址,账号,密码不正确导致的本地测试正常,放到虚拟主机就这样了安装的时候出现这个: 虚拟主机HPH5.5 ,数据库MYSQL 5.6 PHP Warning: include_once(./templates/step…