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 是一个内容寻址的文件系统,其核心部分是一个简单的键值 ...
随机推荐
- 插入排序的优化非希尔【不靠谱地讲可以优化到O(nlogn)】 USACO 丑数
首先我们先介绍一下普通的插排,就是我们现在一般写的那种,效率是O(n^2)的. 普通的插排基于的思想就是找位置,然后插入进去,其他在它后面的元素全部后移,下面是普通插排的代码: #include< ...
- 20170410Linux备课资料 --- 压缩与解压缩
这节课我们来学习一下压缩与解压缩,那什么是压缩与解压缩呢? 联想一下Windows系统: 选中文件,右键选择即可 如果压缩,可以选择要压缩的格式,而解压缩直接选择就可以完成了 Linux是通过命令的方 ...
- 转账示例(四):service层面实现(线程管理Connection,AOP思想,动态代理)(本例采用QueryRunner来执行sql语句,数据源为C3P0)
用了AOP(面向切面编程),实现动态代理,service层面隐藏了开启事务.1.自行创建C3P0Uti,account数据库,导入Jar包 2.Dao层面 接口: package com.learni ...
- 利刃 MVVMLight 6:命令基础
在MVVM Light框架中,事件是WPF应用程序中UI与后台代码进行交互的最主要方式,与传统方式不同,mvvm中主要通过绑定到命令来进行事件的处理, 因此要了解mvvm中处理事件的方式,就必须先熟悉 ...
- ORACLE中关于外键缺少索引的探讨和总结
在ORACLE数据库中,定义外键约束时,ORACLE是不会自动创建对应索引的,必须手动在外键约束相关的列上创建索引.那么外键字段上是否有必要创建索引呢?如果有必要的话,巡检时,如何找出外键字段上没有创 ...
- 各种API总结大全 JAVA、HTML、HTML5等等
本文章,发现新的API会进行更新,如果你们觉得有新的版本或者拥有新的,也可以发有邮箱到"zenglei8732@163.com"当中,本人会在12小时内更新,非常感谢!!! HTM ...
- LinkedList 学习笔记
先摆上JDK1.8中hashMap的类注释:我翻译了一下 /** * Doubly-linked list implementation of the {@code List} and {@code ...
- python——迭代器和生成器
1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大优 ...
- Linux-进程描述(5)之进程环境
main函数和启动例程 当内核使用一个exec函数执行C程序时,在调用main函数之前先调用一个特殊的启动例程,可执行程序将此例程指定为程序的起始地址.启动例程从内核获取命令行参数和环境变量,然后为调 ...
- Gym - 101102C线段树
Judge Bahosain was bored at ACM AmrahCPC 2016 as the winner of the contest had the first rank from t ...