理解git结构与简单操做(三)认识版本库与分支

版本库,也就是git的分支库,实际上是git最核心的部分。当咱们提到git时,其实就是在说git分支。若是你是一个我的开发者,你的项目只有一我的在开发,永远只有一个master分支,那么你可能永远接触不到分支的内容,你对git的了解会永远停留在「了解」这一阶段。git

版本库的基本组成

版本库这个名称来源,就是它管理的是一个个「版本」。segmentfault

版本库是由分支组成的,分支则是由commit组成的。commit就是版本库的基本单位svn

在git中,每一个都commit有一个独一无二的「commit id」,也就是说经过这个id你能够精肯定位到某一个commit上。spa

因此,为何git要求每次commit的时候必须为commit添加明确的commit message,而且要专门开辟出stage暂存区来管理每一次commit的内容(svn就没有暂存区),就是为了可以随时进行commit(代码版本)层面的操做,明确每一次commit,保证出现问题时能快速定位,以及完成版本回退等操做。3d

关于分支

简单的说,分支就是由commit串成的一条时间线,就是这样子的:指针

上面的每一个圈圈都是一次commit。code

在新建git仓库时,git会自动给你建立一条分支,叫master,你以后所作的全部操做都是在这个master分支上操做。不过,并不要把一个分支就理解为是这样的一条时间线。这里可能有点绕,也是git中最抽象的一个点之一。就是:对象

master分支实际上是一个指针,它指向一个commit,表明了在这条时间线上,master指针指向的那个commit时间点的代码状态。可能对于指针概念有基础的同窗会更好理解一点。以下图:blog

当咱们创建一个分支时,使用两种方式:开发

  • git branch <branch name> (仅建立分支)
  • git checkout -b <branch name> (建立分支并切换到该分支)

这样子创建的分支指针会指向目前你所在的那个分支(master),假如咱们建立了一个分支叫dev,那么咱们的时间线就变成了这个样子:

能够看到,时间线仍是那条时间线,不过已经有两条分支同时存在了,只是这两条分支都指向同一个commit,因此两条分支内容彻底相同,git也就只会指一下指针,不会对代码和时间线作任何操做。可是,抽象来看,你能够把这两条分支看做是两条线。

而咱们怎么肯定哪一条分支是咱们当前的分支呢?也是指针,不过是一个指向指针的指针,叫作HEAD。HEAD指针在git中算是个关键字,HEAD就是当前指向当前分支的指针的意思。咱们只用git branch dev建立分支时,HEAD指针不会作改变,当前分支依然是master分支,当前状态如图所示:

当咱们在当前这种状态下,将暂存区中的内容进行一次提交时,会将时间线向前推动,生成一个commit,而后把当前分支master指向最新的commit。如图所示:

当切换分支时,咱们会使用git checkout <branch name>,将HEAD指针指向切换过去的那个分支名。

咱们是否是见到了老朋友checkout!

在前面的暂存区我讲过,checkout做为检出操做是将暂存区中的内容同步到工做区的方法。这里的checkout依然是检出的意思,只不过检出的对象变成了相应分支的文件

其实咱们能够把暂存区想象成一个分支,暂存区的内容就是commit的内容,这两种操做的意义就保持一致了,只不过检出分支时HEAD指针会移动。checkout文件会修改工做区。因此,执行git checkout dev后,分支状态就变成了这样:

而上面说过,checkout会修改工做区,因此你磁盘上的文件就变成了dev分支上那次commit时的样子。而在建立时提到的git commit -b <branch name>则同时完成了「建立分支」和「检出分支」两个操做,方便得很。

使用git branch -av就能够查看全部分支的信息了(a是all,v是verbose)。

涉及操做:git branch <branch name>, git checkout <branch name>

文章连接

理解git结构与简单操做(一)git的本质

理解git结构与简单操做(二)工做区与暂存区

理解git结构与简单操做(三)认识版本库与分支

理解git结构与简单操做(四)合并分支的方法与策略

相关文章
相关标签/搜索