Git分支的简单了解

274 阅读3分钟

什么是分支

简单来说,分支就是一个独立于原开发主线的一个源代码副本,这样就能在修改源程序时无需影响源程序。而修改源程序是在副本上修改,之后与主分支进行合并。但显然这样的效率并不是太高,特别是大型项目,这样的过程特别耗费时间。

这时候Git的优势就显现了,有人吧Git 的分支模型称为它的“必杀技特性”,也正因为这一特性,使得 Git 从众多版本控制系统中脱颖而出。要知道Git分支能脱颖而出,就要先明白Git的实现原理。

Git的实现原理

在Git的官方文档中对于Git的文件保存有这样一句话“ Git 保存的不是文件的变化或者差异,而是一系列不同时刻的 快照 。”,也就是说Git仅仅保存某个时间点,项目里的文件都是什么样的,像一张照片一样。一张照片就代表一个版本,在不同版本切换也就是寻找那个时刻的照片。

而这一切的实现的得益于指针的使用,在我们git commit的时候,Git会保存一个提交对象(commit object),里面就包含了指向暂存的那张照片的指针,当然对象中还包含了作者的姓名和邮箱、提交时输入的信息以及指向它的父对象(即当前对象的前身,可能是空,也可能是两个快照的合并)的指针。

这里我们借用Git官方手册的例子(文章尾有链接)来说明

在我们使用git add提交暂存时,Git会计算每个文件的校验和(使用SHA-1 哈希算法),然后会把文件快照保存在Git仓库中(使用blob对象来保存,如下图的右边三个对象)。

然后,当我们执行以下提交指令时

$ git add README test.rb LICENSE
$ git commit -m 'The initial commit of my project'

Git会计算每个子目录的校验和,然后把这些校验和保存为一个树对象,里面包括除暂存对象包含的信息外,还包含指向这个树对象(项目根目录)的指针。至此,Git就能重现这个时间点项目快照。

首次提交对象及其树结构。

由此可见,一次提交后,Git仓库中有以上5个对象,三个 blob 对象(黄色,保存着文件快照)、一个 对象 (蓝色,记录着目录结构和 blob 对象索引)以及一个 提交 对象(白色,包含着指向前述树对象的指针和所有提交信息)。

当我们多次提交后,提交对象间就会指向上一个提交对象(如下图)

提交对象及其父对象。

Git分支的本质

明白了Git的实现原理,对于Git分支,其实就是就是指向提交对象的一个指针,我们平时所见的master分支仅仅是因为我们一般使用git init来初始化仓库,所以默认生成的分支都叫master,但其实master并没有什么特别,更其他后面创建的分支一样的。

分支及其提交历史。

分支的创建

使用如下命令即可创建一个名为testing的分支,实际上就是一个新的可移动指针。

$ git branch testing

两个指向相同提交历史的分支。

这时可以看到两个分支指向了同一个提交对象,那Git是怎么区分这时候使用的分支是哪个的呢?

在这点上,Git使用了一个名为HEAD的指针,它指向本地当前正使用的分支,由此来区分上述情况。

HEAD 指向当前所在的分支。

我们也能使用如下命令来查看各分支所指对象

$ git log --oneline --decorate
f30ab (HEAD -> master, testing) add feature #32 - ability to add new formats to the central interface
34ac2 Fixed bug #1328 - stack overflow under certain conditions
98ca9 The initial commit of my project

分支切换

使用如下命令即可

$ git checkout testing

参考资料

Git官方文档git-scm.com/book/zh/v2/…分支-分支简介


\