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
这条命令做了两件事:
- 使
HEAD
指回master
分支 - 将工作目录恢复成
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) 查看提交历史
谢谢