当前位置: 首页 > news >正文

图解git原理

用了这么久git,你有没有想过git的原理是什么?为什么git做回退这么快?创建、切换分支也这么快?git的工作区、暂存区、本地仓库、远程仓库都分别对应怎样的实体?打开一个git仓,看看目录下的.git文件夹,所有秘密都藏在这个.git里面。

下面举个栗子说明。我先git init了一个空仓,然后创建了两个txt文件,目录结构如下:

--dir1

   └ a.txt  内容是"hello"

--dir2

   └ b.txt 内容是"world"

然后再git add;此时发生了如下几件事:

  • git分别把各个文件经过计算得到SHA1值,并生成blob object(这种object的内容是文件经过无损压缩后的字节流),并存储到.git/objects目录下。
  • 此外还会更新.git/index文件(即暂存区的索引文件),我们可以用git ls-files --stage来看看它当前的内容:

其中b6fc4c、04fea0这两串数字分别是a.txt和b.txt的SHA1值。

我们去.git/objects里找到这个b6fc4c,打开看看:

 

 是串乱码。因为是被压缩过的。我们可以用git cat-file -t [sha1]来查看它的类型,用git cat-file -p [sha1]来查看它被压缩之前的原始内容:

现在我们执行git commit做一次提交。此时发生了如下几件事:

  • git从此次commit修改的每个文件向上遍历,将其父目录、祖父目录...等等都重新生成tree object(这种object用于记录某个目录的文件结构,即目录树)
  • git生成一个commit object(即一个提交,记录了根目录树的SHA1、父提交的SHA1、以及提交的commit message)
  • git将分支索引文件中的内容替换为这个最新的commit的SHA1

我们从上往下看。先打开.git/HEAD文件(HEAD用来表示当前分支):

当前分支叫refs/heads/master。

我们再打开.git/refs/heads/master:

意思是master分支当前指向37de56这个提交。

那再用git cat-file来看看这个提交的内容:

这个提交指向tree 83c4ae,继续往下看:

tree 83c4ae记录了根目录的结构,它有两个子目录,dir1和dir2,分别对应tree 658293和tree

098076:

这两个tree又分别指向一个blob object。

此时来张图就一目了然了:

上图第1列(绿色)是第一次提交,

修改a.txt的内容,做第二次提交(蓝色),可以看到更新后的a.txt产生了一个新的blob 620ffd,而b.txt我没做修改,所以复用上次的blob 04fea0;并且a.txt的更新影响了其父目录dir1和其祖父目录(即根目录)的tree object的刷新。

将b.txt从dir2移动到dir1,做第三次提交(橙色),由于只是移动,所以没有新的blob产生,但由于我更新了目录结构,所以dir1目录以及根目录需要重新生成tree object。

综上:git使用.git中的各式各样的文件、以及文件之间的指向关系来管理整个仓库。

需要注意的几点:

  • commit object会通过tree object来管理目录结构,但index文件不会指向任何tree object,它直接在自身的内容中记录每个文件的名字和所在的目录。
  • 一旦执行了git add,只要你别删除.git目录,你被add进去的代码就不会丢失。之前我还傻傻以为git reset --hard后文件都没了,实际上.git/objects里对应的blob全都在。

参考资料:这才是真正的Git——Git内部原理揭秘! - 知乎 (zhihu.com)

 

相关文章:

  • 石家庄网页设计的公司/seo教程自学网
  • 做网站要给ftp密码吗/网站seo是什么意思
  • 什么样的网站需要服务器/安卓系统最好优化软件
  • wordpress远程特色图/一键注册所有网站
  • 襄阳做网站哪家好/长沙网站推广有哪些啊
  • 六安推广公司/热狗seo优化外包
  • DOM特效模拟框拖拽
  • ITIL 4 Foundation知识体系-第四章:服务价值体系-2
  • 【备战十四届蓝桥杯 | 开篇】如何高效备战蓝桥杯
  • 北京化工大学2022-2023-1 ACM集训队每周程序设计竞赛(6)题解
  • SpringMVC 5 Rest 风格 5.4 RESTful 案例 5.4.1 需求分析 5.4.2 环境准备
  • Java学习笔记:Java中访问数据库
  • 【程序环境与预处理】
  • 【ASM】字节码操作 转换已有的类 ClassReader 修改字段信息 删除字段 增加字段
  • VIM使用进阶:VIM脚本初步
  • java基于微信小程序的校园二手交易平台+ssm+uinapp+Mysql+计算机毕业设计
  • 【Web】ES6学习笔记
  • 《汇编语言-王爽老师》(第三版)学习笔记-3、实验三