GIT底层原理(一)

git暂存操作原理:git add 

暂存操作会对先每一个文件计算校验和checksum(Git 使用SHA-1 算法计算数据的校验和,通过对文件的内容或目录的结构计算出一个SHA-1 哈希值,作为指纹字符串,该字串由40 个十六进制字符,并将此结果作为数据的唯一标识和索引),然后把当前版本的文件快照保存到本地Git 仓库中(Git 使用blob 类型的对象存储这些文件内容快照),并将校验和加入暂存区域。

注意:所有保存在Git 数据库中的东西都是用此哈希值来作索引的,不是靠文件名。

git commit 原理:

在使用git commit 新建一个提交对象前,Git 会先计算每一个子目录(项目根目录)的校验和,然后在Git 仓库中将这些目录保存为树(tree)对象。之后Git 创建的提交对象,除了包含相关提交信息以外,还包含着指向这个树对象(项目根目录)的指针,如此它就可以在将来需要的时候,重现此次快照的内容了。

例如:一个项目里假如有三个文件ReadME,LICENSE,test.rb,commit后仓库里会保存五个对象。

GIT底层原理(一)_第1张图片

之后修改后再次提交。那么新的commit对象会包含上一次提交对象的指针parent。经过两次提交后,仓库历史结构(git log)

GIT底层原理(一)_第2张图片


git核心“分支“:

git的分支是十分的轻量级,git的新建分支,合并分支等操作几乎是瞬间完成。

1、Git 创建一个新的分支仅仅是创建一个新的分支指针。如:git branch testing 创建一个testing分支;会commit 对象上新建一个分支指针并指向当前commit

GIT底层原理(一)_第3张图片

2、,Git 是如何知道当前在哪个分支上工作的呢?有一个名为HEAD 的特别指针,运行git branch 命令,仅仅是建立了一个新的分支,但不会自动切换到这个分支中,所以当前我们仍然在master分支。

GIT底层原理(一)_第4张图片

3、要切换到其他分支,执行git checkout  命令。我们现在转换到新建的testing 分支:git checkout testing,git仅仅是将HEAD指针指向了testing,几乎瞬间完成。

GIT底层原理(一)_第5张图片

4、如果这时我们再次修改了文件,并提交(git commit ),仅仅是testing分支指向了最新commit ,而master仍指向在原来的commit

GIT底层原理(一)_第6张图片

5、使用git checkout master切换回master分支。git做了两件事它把HEAD 指针移回到master 分支,并把工作目录中的文件换成了master 分支所指向的快照内容。

GIT底层原理(一)_第7张图片


注意:以上1、2、3、4、5 图中的箭头仅仅为了展示git提交的前后顺序。在git中新的commit对象中的parent是指向着上一个commit。

6、在master分支我们修改文件再进行提交,这时项目提交历史产生了分叉。


GIT底层原理(一)_第8张图片


Git 中的分支实际上仅是一个包含所指对象校验和(40 个字符长度SHA-1 字串)的文件,所以创建和销毁一个分支就变得非常廉价。新建一个分支就是向一个文件写入41 个字节(外加一个换行符)。

如果我们有需要我们可以完全再次checkout到testing分支去开发新的功能。我们可以在分支间随意切换,并且都是瞬间切换完成。这和之前大多数版本控制系统形成了鲜明对比,它们管理分支大多采取备份所有项目文件到特定目录的方式,所以根据项目文件数量和大小不同,可能花费的时间也会有相当大的差别,快则几秒,慢则数分钟。而Git 的实现与项目复杂度无关,它永远可以在几毫秒的时间内完成分支的创建和切换。每次提交时都记录了祖先信息(译注:即parent 对象),所以以后要合并分支时,寻找恰当的合并基础(译注:即共同祖先)的工作其实已经完成了一大半。



你可能感兴趣的:(Git)