Git 分支的创建与切换 —— Git 学习笔记 14

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013490896/article/details/82846474

Git 分支的创建与切换

几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响主线的开发。 在很多版本控制系统中,这是一个略微低效的过程 —— 常常需要完全创建一个源代码目录的副本。对于大项目来说,这样的过程会耗费很多时间。

有人把 Git 的分支模型称为它的“必杀技特性”,也正是因为这一特性,使得 Git 从众多版本控制系统中脱颖而出。 为何 Git 的分支模型如此出众呢? Git 处理分支的方式可谓是超级轻量,创建新分支这一操作几乎能在瞬间完成,并且在不同分支之间切换也是一样便捷。

与许多其它版本控制系统不同,Git 鼓励在工作流程中频繁地使用分支与合并。理解和精通这一特性,你便会意识到 Git 是如此强大而又独特,并且从此真正改变你的开发方式。

Git 分支的本质

Git 的分支,其本质上仅仅是指向提交对象的可变指针。说它“可变”是因为它会在每次的提交操作中自动向前移动。 Git 的默认分支名字是 master。 在多次提交操作之后,你其实已经有一个指向最后那个提交对象的 master 分支。
在这里插入图片描述

Git 的 “master” 分支并不是一个特殊分支。 它跟其它分支完全没有区别。 之所以几乎每一个仓库都有 master 分支,是因为 git init 命令默认创建它,并且大多数人都懒得去改动它。

分支创建

Git 是怎么创建新分支的呢? 很简单,它只是为你创建了一个可以移动的新的指针。 比如,创建一个 testing 分支, 你需要使用 git branch 命令:

$ git branch testing

这会在当前所在的提交对象上创建一个指针。

在这里插入图片描述

那么,Git 又是怎么知道当前在哪一个分支上呢? 也很简单,它有一个名为 HEAD 的特殊指针。

请注意它和许多其它版本控制系统(如 Subversion 或 CVS)里的 HEAD 概念完全不同。 在 Git 中,它是一个指针,指向当前所在的本地分支(译注:将 HEAD 想象为当前分支的别名)。 在本例中,你仍然在 master 分支上。 因为 git branch 命令仅仅创建一个新分支,并不会自动切换到新分支上去。

在这里插入图片描述

你可以简单地使用 git log 命令查看各个分支当前所指的对象。 提供这一功能的参数是 --decorate

$ git log --oneline --decorate

f30ab (HEAD -> master, testing) add feature #32 - ability to add new
34ac2 fixed bug #1328 - stack overflow under certain conditions
98ca9 initial commit of my project

正如你所见,当前 “master” 和 “testing” 分支均指向校验和以 f30ab 开头的提交对象,且当前在 master 分支(因为 HEAD 指向 master)。

分支切换

要切换到一个已存在的分支,你需要使用 git checkout 命令。 现在切换到新创建的 testing 分支去:

$ git checkout testing

这样 HEAD 就指向 testing 分支了。

在这里插入图片描述

那么,切换分支会给我们带来什么影响呢? 现在不妨再提交一次:

$ vim test.rb
$ git commit -a -m 'made a change'

提交后的示意图如下:

在这里插入图片描述

看到了吗?你的 testing 分支向前移动了,但是 master 分支却没有,它仍然指向运行 git checkout 时所指的对象。 这就有意思了,现在我们切换回 master 分支看看:

$ git checkout master

在这里插入图片描述

这条命令做了两件事。 一是使 HEAD 指回 master 分支,二是将工作目录恢复成 master 分支所指向的快照内容。 也就是说,你现在做修改的话,项目将始于一个较旧的版本(f30ab)。 本质上来讲,这就是忽略 testing 分支所做的修改,以便于向另一个方向进行开发。

分支切换会改变你工作目录中的文件

在切换分支时,一定要注意你工作目录里的文件会被改变。 如果是切换到一个较旧的分支,你的工作目录会恢复到该分支最后一次提交时的样子。 如果 Git 不能干净利落地完成这个任务,它将禁止切换分支。

我们不妨再做些修改并提交:

$ vim test.rb
$ git commit -a -m 'made other changes'

现在,这个项目的提交历史已经产生了分叉。 因为刚才你创建了一个新分支,并切换过去进行了一些工作,随后又切换回 master 分支进行了另外一些工作。
在这里插入图片描述

你可以简单地使用 git log 命令查看分叉历史。 运行git log --oneline --decorate --graph--all ,它会输出你的提交历史、各个分支的指向以及项目的分支分叉情况。

$ git log --oneline --decorate --graph --all
* c2b9e (HEAD -> master) made other changes
| * 87ab2 (testing) made a change
|/
* f30ab add feature #32 - ability to add new formats to the
* 34ac2 fixed bug #1328 - stack overflow under certain conditions
* 98ca9 initial commit of my project

由于 Git 的分支实质上仅是包含所指对象校验和(长度为 40 的 SHA-1 值字符串)的文件,所以它的创建和销毁都非常高效。 创建一个新分支就相当于往一个文件中写入 41 个字节(40 个字符和 1 个换行符),如此之简单能不快吗?

这与过去大多数版本控制系统形成了鲜明的对比:它们在创建分支时,将所有的项目文件都复制一遍,并保存到一个特定的目录。 完成这样繁琐的过程通常需要好几秒钟,有时甚至需要好几分钟。所需时间的长短,完全取决于项目的规模。而在 Git 中,任何规模的项目都能在瞬间创建新分支。


参考资料

《Pro Git》(Scott Chacon, Ben Straub Version 2.1.14, 2018-05-19)

猜你喜欢

转载自blog.csdn.net/u013490896/article/details/82846474