前篇:
深刻理解Git - 一切皆commithtml
如何从稍微底层一点的角度,从底层实现理解一切皆commit ?git
配合希沃白板课件食用,效果更佳:
【希沃白板5】课件分享 : 《Git 进阶 - 从使用角度深刻理解Git》
https://r302.cc/ke8XdO?platform=enpc&channel=copylink
点击连接直接预览课件3d
git 本质上是一个基于键值对的文件系统。
文件系统,最重要的两个内容,固然就是 文件 和 文件夹 了。code
git 中的 blob object 就是文件系统中的文件,包含 键:一个 hash 值和校验值的组合,值:文件内容。orm
比较特殊的是:blob object 只存内容,不存文件名,文件名在 tree object 中保存。htm
至关于文件系统中的文件夹。对象
提交对象能够理解为对树对象的一层封装,里面包含了提交时间,提交做者等信息,更重要的,里面包含了父提交的ID,由此就能够造成 git 提交的有向无环图。blog
git 的这些对象的数据,保存在 .git/objects 目录下。three
这里,咱们并无发现分支这些概念,回顾以前说的『一切皆 commit』的理解,分支这些,不过是某个 commit 的引用。(都是纸老虎)图片
案例
将 t/bugfix 分支重置到 a1b2c3 提交。
可使用熟悉的 reset 命令: (@t/bugfix)git reset --hard a1b2c3
,也能够用更底层的命令:git update-ref refs/head/t/bugfix a1b2c3
。
效果是同样的,固然,平时使用,只推荐前者,这里只是做为对“分支是某个commit的引用”这句话理解的一个案例。
tag object(标签对象)
标签对象:指向一个特定对象的固定引用对象;
能够给 git 中的任意对象打标签;
标签对象不是引用(与分支名不一样),是一种独立的git对象。但在使用上(针对提交的tag),体验一致。因此“一切皆commit”这句话,对标签而言,是不必定正确的,但实际使用中,通常只会给提交打标签。
全部的引用,都记录在 .git\refs 文件夹中。
在没有压缩时,称 git 的存储模式为松散的对象模式,即一个文件的不一样版本,都是保存其所有的数据。在 git gc 时,会压缩并实现增量存储。这个命令在执行 pull 等命令时自动触发。
由于提交的不可变性,如图,若是 newfile 是个大文件,即便删除,在提交历史中依然存在。要完全删除,就要重写 second 提交以及以后的每个提交,由于以后的提交都有 tree 指向这个大文件,即便删除,提交的父提交也须要变化。
如
勘误:这里的 three,应该是 third 。图片中也写错了,就懒得改了。
原文链接:http://www.javashuo.com/article/p-ustuggna-kg.html
END