Git分支

Git分支

Git分支功能可谓是Git的“必杀技特性”, 因为很多其它版本控制系统中,分支功能很慢,因为需要完全创建一个源代码目录的副本。
Git处理分的操作非常轻量,切换也非常快,Git鼓励在工作流程中频繁使用分支与合并,理解和精通分支特性,会大大提高开发效率。

分支简介

如前文所说,Git保存的是一系列不同时刻的文件快照。
而Git的分支,本质上仅仅是至指向提交对象的可变指针

分支创建

git branch [branch-name]命令可以创建新分支,本质上是创建了一个新的可移动的指针,且这个命令只创建而不切换到新创建的分支,与之对应的,可以用git checkout -b [branch-name]创建并切换到一个新分支。

Git通过一个特殊的HEAD指针指向当前所在的本地分支
git log --decorate命令可以查看当前各个分支当前所指向的对象,例如,假设我们在当前分支上创建了一个新分支,而没有发生任何其它改变,使用该命令可以看到如下信息:

1
2
3
4
$ 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

可以看到mastertest分支都指向校验和以f30ab开头的提交对象,这也验证了之前说的,分支仅仅是指向提交对象的可变指针。

分支切换

要切换到一个已存在分支,可以使用git checkout命令,这个命令会把HEAD指针指向要切换的分支上

由于Git的分支是指向提交对象的可变指针,其包含的内容是所指向对象的校验和(长度为40的SHA-1值字符串),因此Git分支的创建和销毁都异常的高效,无论项目本身多大,都能瞬间创建新分支。这样高效的特性使得Git鼓励开发人员频繁的创建和使用分支。

分支的新建与合并

通过一个简单的例子描述,假设我们要经历以下步骤:

  1. 开发某个网站
  2. 为实现某个新需求,创建一个新分支
  3. 在该分支上开展工作

此时,突然线上有紧急问题需要处理,我们将按照如下方式处理:

  1. 切换到线上分支(production branch)
  2. 为紧急任务新建一个分支并在其中修复它
  3. 测试通过后,切换回线上分支,然后合并修补分支,再将改动推送到线上分支
  4. 切换回最初工作的分支,继续工作

分支管理

git branch 不加任何参数运行,可以得到当前所有分支的一个列表, 分支前面带*的表示当前分支

git branch -v可以查看每个分支的最后一次提交

--merged--no-merged 这两个选项可以过滤列表中已经合并到或者尚未合并到当前分支的分支。
git branch --merged可以展示已经合并到当前分支的分支(包括当前分支)git branch --no-merged可以展示包含所有未合并工作的分支。

git branch -d [branch-name] 在一个分支完成其功能且合并后可以删除掉不必要的分支,使得仓库更简洁。另外,对于一些没合并但确认没用的分支,可以用git branch -D [branch-name]强制删除

分支开发工作流

通常有两种分支开发模式:

  • 长期分支: 受益于Git分支效率,可以短时间多次合并,因此,例如我们可以设置一个master分支和一个develop分支,master分支用于发布的稳定版本,而develop分支一直用于开发,稳定后合并入主分支。长期如此进行。
  • 特性分支:为了解决或者试验某种特性临时创建的分支,比如突然出现了一个热点问题或者试验我们某个不确定的想法,为了不影响其它工作可以创建一个特性分支专门处理,处理完成后合并并删除。

变基

git中整合来自不同分支的修改有两种方法,一个是之前提到过的merge,另外一个就是变基rebase
假设有两个从同一个父节点分叉出来了两个分支experiment和master,现在要将experiment的工作合并到master,通过checkout命令切换到master分支,然后执行merge命令可以胜任,但是会在历史上留下一个experiment分支的信息。使得Git历史不那么简洁,那么可以使用rebase命令,具体操作是,checkout命令切换到experiment分支,然后执行git rebase master将experiment分支的工作变基到master分支,然后再切换到master分支执行一次merge,此时执行的merge是快进合并(沿着一个分支走可以直接走到目标节点,无需其它操作)
变基的原理是找到两个分支的最近祖先,然后将当前要变基分支(experiment分支)相对于最近祖先的变化在master分支上重新应用一次。

变基 vs 合并
对应git的两种思想,前者是说要保持git仓库的简洁,后者是说要忠实记录所有的开发历史,根据需要选择即可。

实际变基操作中,我们要牢记原则:只对尚未推送或者分享给别人的本地修改执行变基操作清理历史,而不要对已推送到别处的提交执变基操作(因为可能出现很混乱的问题)


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!