Git笔记(11) 分支简介


1. Git 分支

使用分支可以把工作 从开发主线上分离 开来,以免影响开发主线
在很多版本控制系统中,依靠完全创建副本,但这是一个略微低效的过程

而 Git 处理分支的方式超级轻量
创建新分支可瞬间完成,并且在不同分支之间的切换操作也便捷

与许多其它版本控制系统不同
Git 鼓励在工作流程中频繁地使用分支与合并


2. 简介

介绍分支需要从 Git 是如何保存数据的开始说起
Git学习笔记(1) 版本控制 中提到 Git 保存的不是文件的变化或者差异
而是一系列不同时刻的 文件快照

在进行提交操作时,Git 会保存一个提交对象(commit object
可以很自然的想到——该 提交对象会包含一个指向暂存内容快照的指针

该提交对象还包含了作者的姓名和邮箱、提交时输入的信息以及指向它的父对象的指针
首次提交产生的提交对象没有父对象,普通提交操作产生的提交对象有一个父对象
而由多个分支合并产生的提交对象有多个父对象

为了更加形象地说明
假设现在有一个工作目录,里面包含了3个将要被暂存和提交的文件
暂存操作会为每一个文件计算校验和
然后会把当前版本的文件快照保存到 Git 仓库中(Git 使用 blob 对象来保存它们)
最终将校验和加入到暂存区域等待提交:

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

当使用 git commit 进行提交操作时
Git 会先计算每一个子目录(本例中只有项目根目录)的校验和
然后在 Git 仓库中这些校验和保存为 树对象

随后,Git 便会创建一个提交对象
它除了包含上面提到的那些信息外,还包含指向这个树对象(项目根目录)的指针
如此一来,Git 就可以在需要的时候重现此次保存的快照
在这里插入图片描述

现在,Git 仓库中有五个对象:

  • 一个提交对象(包含着指向前述树对象的指针和所有提交信息)
  • 一个树对象(记录着目录结构和 blob 对象索引)
  • 三个 blob 对象(保存着文件快照)

做些修改后再次提交
那么这次产生的提交对象会包含一个指向上次提交对象(父对象)的指针
在这里插入图片描述
Git 的分支,其实本质上仅仅是 指向提交对象的可变指针
即仅是包含所指对象校验和的文件
创建一个新分支就相当于往一个文件中写入 41 个字节(40 个字符和 1 个换行符)
所以它的创建和销毁都异常高效

Git 的默认分支名字是 master
在多次提交操作之后,其实已经有一个指向最后那个提交对象的 master 分支
它会在每次的提交操作中自动向前移动
在这里插入图片描述

master 分支不是一个特殊分支,只是因为默认创建,跟其它分支完全没有区别


3. 创建

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

$ git branch testing

这会在当前所在的提交对象上创建一个指针
在这里插入图片描述


4. 查看当前分支

有一个名为 HEAD 的特殊指针,指向当前所在的本地分支
HEAD 想象为当前分支的别名

在上面的例中,创建 一个新分支,并不会自动切换到新分支中去
在这里插入图片描述

可以简单地使用 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 开头的提交对象


5. 切换

Git学习笔记(9) 打标签 中提及到使用 git checkout 命令查看某个标签所指向的文件版本
同时也提及到这个命令使仓库处于“分离头指针(detacthed HEAD)”状态
很明显,就是改变了 HEAD 特殊指针
那么利用 git checkout 切换到一个已存在的分支

例如,现在切换到新创建的 testing 分支去:

$ git checkout testing

这样 HEAD 就指向 testing 分支了

在这里插入图片描述

现在不妨进行修改文件,然后再提交一次:

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

在这里插入图片描述
testing 分支向前移动了
但是 master 分支却没有,它仍然指向运行 git checkout 时所指的对象

现在切换回 master 分支:

$ git checkout master

在这里插入图片描述

这条命令做了两件事:

  1. 使 HEAD 指回 master 分支
  2. 将工作目录恢复成 master 分支所指向的快照内容

现在做修改的话,项目将始于一个较旧的版本
本质上来讲,这就是忽略 testing 分支所做的修改,以便于向另一个方向进行开发


6. 分叉

不妨再稍微做些修改并提交:

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

现在,这个项目的提交历史已经产生了分叉
在这里插入图片描述
上述两次改动针对的是不同分支:
可以在不同分支间不断地来回切换和工作,并在时机成熟时将它们合并起来

运行 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
以上内容,均根据git官网介绍删减、添加和修改组成


相关推荐:

Git笔记(10) 别名
Git笔记(9) 打标签
Git笔记(8) 远程仓库的使用
Git笔记(7) 撤消操作
Git笔记(6) 查看提交历史


谢谢

发布了242 篇原创文章 · 获赞 327 · 访问量 305万+

猜你喜欢

转载自blog.csdn.net/qq_32618327/article/details/104275410