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 原理简谈的更多相关文章

  1. Git原理入门简析

    为了获得更好的阅读体验,建议访问原地址:传送门 前言: 之前听过公司大佬分享过 Git 原理之后就想来自己总结一下,最近一忙起来就拖得久了,本来想塞更多的干货,但是不喜欢拖太久,所以先出一版足够入门的 ...

  2. .NET简谈构件系统开发模式

    转自[王清培] http://www.cnblogs.com/wangiqngpei557/archive/2011/06/14/2080416.html 在本人的“.NET简谈插件系统开发模式”一文 ...

  3. 简谈Java语言的封装

    简谈Java语言的封装 封装的定义 封装将复杂模块或系统的逻辑实现细节隐藏,让使用者只需要关心这个模块或系统怎么使用,而不用关心这个模块或系统是怎么实现的. 在面向对象的的编程中,我们一般通过接口来描 ...

  4. Java线上问题排查神器Arthas快速上手与原理浅谈

    前言 当你兴冲冲地开始运行自己的Java项目时,你是否遇到过如下问题: 程序在稳定运行了,可是实现的功能点了没反应. 为了修复Bug而上线的新版本,上线后发现Bug依然在,却想不通哪里有问题? 想到可 ...

  5. Git原理及常用操作命令总结

    git原理介绍及操作 git 原理——

  6. .NET简谈接口

    自从面向对象开发方式的出现,抽象的概念就开始日新月异的发展,面向对象编程.面向接口编程.面向组件编程等等:这一系列的概念都是软件工程所追求的思想范畴,高类聚低耦合. 今天我要简谈的是面向对象里面非常重 ...

  7. Java Android 注解(Annotation) 及几个常用开源项目注解原理简析

    不少开源库(ButterKnife.Retrofit.ActiveAndroid等等)都用到了注解的方式来简化代码提高开发效率. 本文简单介绍下 Annotation 示例.概念及作用.分类.自定义. ...

  8. PHP的错误报错级别设置原理简析

    原理简析 摘录php.ini文件的默认配置(php5.4): ; Common Values: ; E_ALL (Show all errors, warnings and notices inclu ...

  9. Java Annotation 及几个常用开源项目注解原理简析

    PDF 版: Java Annotation.pdf, PPT 版:Java Annotation.pptx, Keynote 版:Java Annotation.key 一.Annotation 示 ...

随机推荐

  1. HTML5的一些验证挺方便的

    一些基本的验证都可以很简单的实现,节省了很多繁琐的步骤.

  2. 申请SSL证书

    1.为什么需要申请SSL证书呢? 因为之前公司网站是通过http访问的,现在要通过https方式访问,前面多了一个s,那就需要SSL证书,用https方式访问的,会加密用户上传和下载的数据,使访问更加 ...

  3. SpringBoot整合freemarker模板

    一.目录展示 二.导入依赖 三.application.properties配置文件 四.在src/main/resource/templates文件夹中创建HelloFreeMarker.ftl文件 ...

  4. ubuntu部署.Net Core3.1(Nginx+pm2)

    前言 虽然.NetCore已经出来很久了,但是很多初学者还是不会在linux部署.所以写一篇初学者在ubuntu下部署Core的全过程,大佬请无视. 环境搭建 ubuntu18.04 NetCore3 ...

  5. 19.JAVA-从文件中解析json、并写入Json文件(详解)

    1.json介绍 json与xml相比, 对数据的描述性比XML较差,但是数据体积小,传递速度更快. json数据的书写格式是"名称:值对",比如: "Name" ...

  6. git 使用详解(3)—— 最基本命令 + .gitignore 文件

    Git 基础 本章将介绍几个最基本的,也是最常用的 Git 命令,以后绝大多数时间里用到的也就是这几个命令.读完本章,你就能初始化一个新的代码仓库,做一些适当配置:开始或停止跟踪某些文件:暂存或提交某 ...

  7. 移动开发在路上-- IOS移动开发 五 网络请求封装

    接着上次的讲,这次我们讲 网络请求的封装  打开创建的项目,让我们一起来继续完成他, 上次我们说到GET请求地址的拼接: 我们接着上次的继续完善: 下边我们要定义的是 block //定义block ...

  8. Bless You Autocorrect!

    题目链接: https://odzkskevi.qnssl.com/0c87453efec2747f8e8a573525fd42f9?v=1533651456 题解: 这是一道Trie+BFS的题目: ...

  9. (全国多校重现赛一) J-Two strings

    Giving two strings and you should judge if they are matched.  The first string contains lowercase le ...

  10. TypeScript - 类型声明、枚举、函数、接口

    目录  可定义的类型  类型声明  枚举  函数  接口 可定义的类型 以下所写的并不代表typescript的数据类型,而是在使用过程中可以用作定义的类型 number : 数值类型: string ...