git底层原理(二)
git对象模型
在git系统中有四种类型的对象,所有的Git操作都是基于这四种类型的对象:
"blob":这种对象用来保存文件的内容。
"tree":可以理解成一个对象关系树,它管理一些"tree"和“blob”对象。
"commit":指向一个"tree",它用来标记项目某一个特定时间点的状态。它包括以下关于时间点的元数据,如时间戳、最近一次提交的作者、指向上次提交等。
"tag":给某个提交增添一个标记。
SHA1哈希值
在Git系统中,每个Git对象都有一个特殊的ID来代表这个对象,这个特殊的ID就是我们所说的SHA1哈希值。SHA1哈希值是通过SHA1算法计算出来的哈希值,对于内容不同的对象,会有不同的SHA1哈希值。
实例
我们以这样的目录结构为例来研究,
--repository //根目录文件夹
--a.txt //txt文件,初始时,内容为a_git
--bb //文件夹
--b.txt //txt文件,在bb文件夹下面,内容为b_git
首先cd repository目录,初始化使用git init命令,执行了这个命令后repository目录下会生成一个.git文件夹,使用find . -type f命令查看目录结构:

然后执行git add -A和git commit -m "commit1"两条命令,可以看到.git/objects/文件夹下增加了五个对象

可是我们的示例工程只有两个文件和一个文件夹,为什么objects里却有五个文件那,这里就要说说commit类型了,commit类型内部可以引用一个tree类型文件和一个commit类型文件。
关于文件的名字,objects内部的文件全部是以sha-1命名,如果是blob类型则以文件内容做sha-1计算得出40字符的校验和,然后为了不让这个objects内部文件过多,所以使用40字符的前两位来建立一个文件夹,在以后38位为文件名,包括commit 和tree 全部使用sha-1校验和来命名。
接下来说一下这五个文件是以什么结构关联的:
每个commit 引用一个tree,根据工程目录结构这个tree 再引用一个blob(a.txt)和一个tree(bb) ,这个tree(bb)则引用一个blob(b.txt)如图:

通过这个图就可以看出来commit,tree,blob的关系了,也基本能明白为什么objects下有五个文件了, 现在我改动一下a.txt然后在提交一个版本,在a.txt添加"123456"内容然后执行add和commit,添加一个版本,接下来再看objects内部的情况:

比刚刚多了三个文件,究竟是哪三个文件?因为我们改动了a.txt文件,所以这里在保留上一个版本的a.txt的基础上新增加一个a.txt文件,git只对有改动的文件进行备份保留。另外两个文件分别是commit 2和一个根tree,现在这8个文件的关系如图:

commit文件内部可以引用一个commit,这样commit之间就可以建立关系了,因为只有a.txt文件做了改动所以只有a.txt文件新建了一个,然后被commit2引用,bb和b.txt文件未做改动则commit2依然引用之前的文件。同理如果我们再改动b.txt文件,我们可以设想一下这些文件的关联关系。如图:

branch分支
git branch 可以获取当前的分支列表,这个分支列表会保存在./git/refs/heads/这个路径下,这里包含master和一些其他分支文件,以master文件为例查看master文件内容如下:

其实这是一个commit类型 的文件名,这样每个分支都可以拥有一个自己的commit引用,从上面的图可以看出只要拿到commit的文件名就可以找到所有跟他关联的文件,还有个问题是./git/refs/heads/这个文件下是所有分支信息,总要有一个当前分支,其实这个当前分支是被记录在./git/HEAD文件内部:

因为当前是master分支所以HEAD文件里记录的是master,每次我们使用git checkout 来切换分支的时候就是在修改HEAD这个文件的内容。那么我们基本就可以理解:我们首先选择一个分支为当前分支,每个分支里记录着当前分支最顶端的commit对象,这个commit对象又可以找到所有跟它关联tree和blob,同时commit对象又和它的历史commit关联。我们可以任意切换当前分支,同时又可以修改当前分支指向的commit对象,比如我们执行reset可以选择回退到任意一个commit。这些就可以顺理成章切换任意分支并且找到任意版本的文件了。
git底层原理(二)的更多相关文章
- iOS 技术篇:从使用到了解block底层原理 (二)
block实质 序言 上篇文章中主要通过简单的demo展示了block的使用场景,本篇将基于上篇文章iOS 技术篇:从使用到了解block底层原理 (一)进一步了解block底层的实现原理. bloc ...
- [置顶] Asp.Net底层原理(二、写自己的Asp.Net框架)
我们介绍过了浏览器和服务器之间的交互过程,接下来介绍Asp.net处理动态请求. 写自己的Asp.Net框架,我们不会引用System.Web这个程序集,我们只需要创建要给自己的类库,所以在接下来的程 ...
- git底层原理(一)
1.git仓库的初始化: 输入git init指令,会看到在当前空目录下创建了一个.git隐藏文件夹,这个就是git实现一切版本管理的关键.进入到.git目录下,里面包含三个文件(config/des ...
- git的核心命令使用和底层原理解析
文章目录: GIT体系概述 GIT 核心命令使用 GIT 底层原理 一.GIT体系概述 GIT 与 svn 主要区别: 存储方式不一样 使用方式不一样 管理模式不一样 1.存储方式区别 GIT把内容按 ...
- 深入源码分析SpringMVC底层原理(二)
原文链接:深入源码分析SpringMVC底层原理(二) 文章目录 深入分析SpringMVC请求处理过程 1. DispatcherServlet处理请求 1.1 寻找Handler 1.2 没有找到 ...
- 【Spring Data JPA篇】JPA的底层原理(二)
一.接口继承结构 二.底层原理
- 【T-SQL进阶】02.理解SQL查询的底层原理
本系列[T-SQL]主要是针对T-SQL的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础]02.联接查询 [T-SQL基础]03.子查询 [T-SQL基础]04.表表达式 ...
- Git详解之九:Git内部原理
Git 内部原理 不管你是从前面的章节直接跳到了本章,还是读完了其余各章一直到这,你都将在本章见识 Git 的内部工作原理和实现方式.我个人发现学习这些内容对于理解 Git 的用处和强大是非常重要的, ...
- 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
本文由云+社区发表 作者:腾讯工蜂用户:王二卫 从不一样的视角了解git,以便更好的使用git 一.git & git 版本库认识 git 是一个内容寻址的文件系统,其核心部分是一个简单的键值 ...
随机推荐
- java 基础知识七 装箱和拆箱
java 基础知识七 装箱和拆箱 数据类型可分为两大种,基本数据类型(值类型)和类类型(引用数据类型) 装箱:把基本类型用他们相对应的引用类型包装起来,使他们可以具有对象的特质 基本数据类型 ...
- 浩哥解析MyBatis源码(八)——Type类型模块之TypeAliasRegistry(类型别名注册器)
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6705769.html 1.回顾 前面几篇讲了数据源模块,这和之前的事务模块都是enviro ...
- 人生第一次hash
人生的第一次hash交给了模板题. 讲道理,还没有别人快排要快,就比暴力快那么一点... 难道我写的hash就那么菜么? 我想了想,光是处理字符串就O(n*len).. 这是hash的正确写法吗?我都 ...
- 透视I/O多路复用
透视I/O多路复用 我写的不是select这些函数的教学,需要了解的请自行Google或者去man,这些是帮助我理解函数的封装之下的道理. 需要回答的问题 I/O准备好了指什么?什么叫I/O已经可读/ ...
- 纯css兼容个浏览器input[type='radio']不能自定义样式
各个浏览器对于表单input[type='radio'].input[type='checkbox']的样式总是各有差异 //html <div class="remember-a ...
- HTTP上传 文件上传 图片上传 HTTP上传原理 文件上传原理 图片上传原理
1.概述 在最初的http协议中,没有上传文件方面的功能.rfc1867(http://www.ietf.org/rfc/rfc1867.txt )为http协议添加了这个功能.浏览器按照此规范将用户 ...
- JS自定义对象,正则表达式,JQuery中的一些知识点
一:自定义对象 1.基本概念:①对象:包含一系列无序属性和方法的集合.②键值对:对象中的数据是以键值对的形式存在的,以键取值.③属性:描述对象特征的一系列变量.[对象中的变量]④方法:描述对象行为的一 ...
- ClickHouse 快速入门
ClickHouse 是什么 ClickHouse 是一个开源的面向联机分析处理(OLAP, On-Line Analytical Processing) 的列式存储数据库管理系统. 在一个 &quo ...
- Centos 7 安装mysql后出现 ERROR 2002 (HY000)解决方案
Centos 7 安装mysql后出现 ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib ...
- Laravel 中使用 Redis 数据库
一.前言 Redis 是一个开源高效的键值对存储系统,它通常用作为一个数据结构服务器来存储键值对,它可以支持字符串.散列.列表.集合.有序集合. 1. 安装 predis/predis 在 Larav ...