Git 原理简谈
Git 本身是一个对 reference 进行管理的数据库,reference 指的是对原始数据的引用。通过对原始数据的追踪,那么就可以做到对版本的控制。Git 使用一个 DAG 存储了整个的reference,根据DAG 的特性,你不会找到一个环,也就是说对于版本的控制始终是有顺序保证的。
Git 有三个最基本的元素,Commit,Tree 和 Blob。Commit 记录了一次commit需要的信息,作者,comment和指向tree的指针。Tree 是一个指针,指向 Blob 和其他的 Tree,Tree 在逻辑上类似于 Unix 文件系统的文件夹,总对应着当前文件夹的情况。Blob 就是数据本身,例如代码或者其他本身需要追踪的数据。Tree 数据和 Blob 数据在逻辑上类似于文件夹和文件夹下的文件的关系。
Git 使用了SHA值作为文件名,对于三种内置类型的数据,都采用他们的本身计算出的 SHA-1 值作为文件名。为了方便索引,会把 SHA 值的前几个字符当作文件,然后进行索引。所有的文件都存储在 .git/ 目录。
Git 基本的工作模型如下
每一个 branch 会记录了一个对应的 commit,如果有多个 branch 就记录对应的 commit 信息。一次commit在逻辑上代表了一次的版本。每一次的 commit 指向了上一次的commit 和一个 tree。显然,指向上一次的 commit 是用来进行每一次版本控制,每一个的 tree 则是用来指向当前的文件夹信息,这里 tree 也有指向另一个 tree 的部分,这说明这当中有文件夹嵌套出现,一个文件夹中还有一个文件夹就会出现这样的情况。blob 就是对应的文件信息。
一个最基本的 Git 模型如下。

我们可以使用一个最基本的文件夹进行说明。在初始化的时候,产生所有的文件如图所示。

这里,我们重点关注 .git/objects/ 下的文件,git 产生的三种内置类型的文件都会存放在这里。
在使用 git add 命令新添加了一个文件的时候,我们可以看到 .git/objects/ 文件下已经有了新的数据。这个 1d0aaf744db6fea2b31826dc11a36ade43fdfdd9 是文件计算的 SHA-1 结果,存放在 1d 文件夹下是方便进行索引。我们可以使用 git 命令查看这个文件类型和文件内容。

使用 git cat-file -t {SHA-1 名} 可以用来查看文件类型, git cat-file -p {SHA-1名} 可以用来查看文件内容。
查看结果如下

可以看到这个记录是 blob 类型,也就是记录了原始的数据。原始的数据内容我们也可以看到。
在进行 git commit 命令之后,我们继续看下文件夹的变化。

此时,多了两个新的文件,分别是 a918c…. 和 41131a….,这两个文件对应的是 tree 类型的文件和 commit 类型的文件,通过 commit 信息,我们可以知道 a918c… 是 commit 类型的文件,而 41131a… 是 tree 类型的文件。
根据 git cat-file 命令,我们可以看到具体的 tree 文件的内容。指向了 blob 类型的文件,文件名是 1d0a… 真实对应的文件名是 foo.txt 。具体的 commit 文件记录了 Author 信息,comment 信息,并指向了一个对应的 tree 文件。


接下来,我们进行新的一次 commit,继续看看对应的 commit 文件信息和 tree 的信息。


可以看到,新的 commit 信息记录了上次的 commit 文件的名称,方便进行切换版本,也记录了这次的 tree 文件的信息。tree 文件记录了对应两个 blob 实体的名称。
如果新创建了一个文件夹,然后在文件夹中添加新的文件,就会出现 tree 指向新的 tree 文件的情况。而另一个tree 指向自己对应的文件信息

如果创建了新的 branch,那么会在对应的 .git/refs/heads 目录下创建新的 branch 文件,并指向此时的 commit 文件。
如果在新的 branch 中,改变了原来的文件,那么会直接创建一个新的 blob,记录这个文件信息,并且改变 tree 原来指向的位置,即两个文件是两个完全不同,但都存在的文件。
如在 new_branch 中,改变了 foo.txt 内容,那么此时 tree 指向的文件也发生了变化,有了在这个分支中新添加的文件,也有了改变的文件。

而在原先的 master 分支中,tree 仍然记录的是之前的信息。

Git 原理简谈的更多相关文章
- Git原理入门简析
为了获得更好的阅读体验,建议访问原地址:传送门 前言: 之前听过公司大佬分享过 Git 原理之后就想来自己总结一下,最近一忙起来就拖得久了,本来想塞更多的干货,但是不喜欢拖太久,所以先出一版足够入门的 ...
- .NET简谈构件系统开发模式
转自[王清培] http://www.cnblogs.com/wangiqngpei557/archive/2011/06/14/2080416.html 在本人的“.NET简谈插件系统开发模式”一文 ...
- 简谈Java语言的封装
简谈Java语言的封装 封装的定义 封装将复杂模块或系统的逻辑实现细节隐藏,让使用者只需要关心这个模块或系统怎么使用,而不用关心这个模块或系统是怎么实现的. 在面向对象的的编程中,我们一般通过接口来描 ...
- Java线上问题排查神器Arthas快速上手与原理浅谈
前言 当你兴冲冲地开始运行自己的Java项目时,你是否遇到过如下问题: 程序在稳定运行了,可是实现的功能点了没反应. 为了修复Bug而上线的新版本,上线后发现Bug依然在,却想不通哪里有问题? 想到可 ...
- Git原理及常用操作命令总结
git原理介绍及操作 git 原理——
- .NET简谈接口
自从面向对象开发方式的出现,抽象的概念就开始日新月异的发展,面向对象编程.面向接口编程.面向组件编程等等:这一系列的概念都是软件工程所追求的思想范畴,高类聚低耦合. 今天我要简谈的是面向对象里面非常重 ...
- Java Android 注解(Annotation) 及几个常用开源项目注解原理简析
不少开源库(ButterKnife.Retrofit.ActiveAndroid等等)都用到了注解的方式来简化代码提高开发效率. 本文简单介绍下 Annotation 示例.概念及作用.分类.自定义. ...
- PHP的错误报错级别设置原理简析
原理简析 摘录php.ini文件的默认配置(php5.4): ; Common Values: ; E_ALL (Show all errors, warnings and notices inclu ...
- Java Annotation 及几个常用开源项目注解原理简析
PDF 版: Java Annotation.pdf, PPT 版:Java Annotation.pptx, Keynote 版:Java Annotation.key 一.Annotation 示 ...
随机推荐
- 【JavaEE】之MyBatis插入数据后获取自增主键
很多时候,我们都需要在插入一条数据后回过头来获取到这条数据在数据表中的自增主键,便于后续操作.针对这个问题,有两种解决方案: 先插入,后查询.我们可以先插入一条数据,然后根据插入的数据的各个字段值,再 ...
- 04-kubernetes 资源清单定义入门
目录 资源对象 创建资源的方法 清单帮助命令 创建测试清单 资源的三种创建方式 资源对象 workload:Pod, ReplicaSet, Deployment, StatefulSet, Daem ...
- VLAN实验4(在eNSP上利用单臂路由实现VLAN间路由)
原理概述: 以太网中,通常会使用VLAN技术隔离二层广播域来减少广播的影响*并增强 网络的安全性和可管理性.其缺点足同时也严格地隔离了不同VLAN之间的任何二层流量,使分属于不同VLAN的用户 不能直 ...
- python拆包
如果需要把原组A赋值给args 字典B 赋值给kwargs 在调用函数的时候需要给参数 加上星号*
- 上手spring boot项目(二)之spring boot整合shiro安全框架
题记:在学习了springboot和thymeleaf之后,想完成一个项目练练手,于是使用springboot+mybatis和thymeleaf完成一个博客系统,在完成的过程中出现的一些问题,将这些 ...
- 利用 FC + OSS 快速搭建 Serverless 实时按需图像处理服务
作者:泽尘 简介 随着具有不同屏幕尺寸和分辨率设备的爆炸式增长,开发人员经常需要提供各种尺寸的图像,从而确保良好的用户体验.目前比较常见的做法是预先为一份图像存放多份具有不同尺寸的副本,在前端根据用户 ...
- IJKPlayer如何支持https
给ijkplayer安装支持https 首先使用如下终端命令安装yasm 第一: 1. curl http://www.tortall.NET/projects/yasm/releases/yasm- ...
- mininet(三)简单的NAT实验
mininet(一)实验环境搭建 mininet(二)简单的路由实验 mininet(三)简单的NAT实验 本次实验拓扑图如下: 假设 Openvswitch switch1是一个带有NAT功能的路由 ...
- 在Linux中配置jdk,Tomcat,MySQL
解压缩: tar 命令 : 使用方式 tar [参数] source [target] source - 压缩文件 target - 解压缩后的目标位置, 默认解压到当前目录 常用写法 : 解压缩 : ...
- [TimLinux] JavaScript 阻止父节点接收子节点事件的方法
1. 事件 两种类型的事件:触发式.冒泡式 2. 冒泡式 触发式:事件从DOM结构的顶层往下走的事件触发过程: 冒泡式:事件从DOM结构的底层往上走的事件触发过程. 3. 父子节点 当父.子节点同时对 ...