Git 分支管理

本篇文章主要讨论 git 分支的操作,在此之前,可以看看前面的文章:


master 分支

每个 Git 仓库创建的时候都会将 master 作为默认分支,你在默认情况下的所有 commit 都是在 master 分支上。

而在 Git 内部,每个 commit 都连接着前一个 commit,以链表的形式进行组织,就像下图这样:

commit list

( 注:下面的乱码是计算机存储的哈希值 )

图中的 HEAD 指针总是指向本地仓库当前的分支,在本例中是 master,而 master 主分支的指针,会指向一个 commit,这也是当前分支最新的 commit。


分支管理

想象这样的场景

你发起了一个大项目,希望多个人协同为项目写代码,而每个人的分工不同:

  • 甲负责开发新的功能
  • 乙负责修 Bug
  • 你负责维护整个项目

甲和乙在打完自己自己的代码的情况下,把自己的代码分别 commit ,然后都 push 到了master 分支上。然后分支上交替出现了这些 commit:

“Add function #1”, “Fix bug #4”, “Fix bug #5”, “Add function #2” …

emmmmm… 只是 commit 有点乱,似乎还能接受。

但是问题来了,甲负责新加功能,然而功能根本没有写完,这时候原本能跑的程序根本无法运行!然后,你发现自己根本无法维护代码……你就疯了。


单分支窘境

我们从上面随手编的小故事可以发现,如果只有一个分支,不仅会使得开发变得非常混乱,而且难以维护。

解决方案也很简单:让不同的分支负责不同的功能


多分支开发

还是刚才的故事,如果你们的开发遵循以下规则:

  • master 分支负责保存所有可以发布的 commit。

  • 甲在一个名叫 Develop 的分支开发,功能开发完成合并到 master 中。

  • 乙在 FixBug 分支上改 Bug,改完 Bug 将分支合并到 master 中。

这样能够使得你的开发变得分工明确,不易出错便于管理。


Vincent Driessen 分支策略

Vincent Driessen 提出的一个分支管理的策略,可以使得版本库的演进保持简洁,主干清晰,各个分支各司其职、井井有条。


1. master 分支

master 分支只负责 commit 重大版本,所有用于发布的版本都会在 master 分支上。

branch-master


2. develop 分支

develop 分支负责日常开发,开发完成则 合并( Merge ) 到 master 分支。

branch-develop


3. feature 分支

feature 开发一些功能,开发完成后合并到 develop 分支,然后删除。

branch-feature


4. fixBug 分支

用于修复在 master 和 develop 分支中的 Bug,修复完成后合并入 develop 和 master 分支,之后删除。

branch-fixBug


总结

  1. master 分支上只有较大的可发布版本。
  2. develop 分支负责日常开发。
  3. 一般来说,只有 masterdevelop 两个分支。
  4. 添加新的功能时,从 develop 分支新建 feature 分支,功能完成后合并入 develop,然后删除 feature 分支。
  5. 遇到 bug 时候,从 develop 分支新建 fixBug 分支,修补完成后合并入 masterdevelop 分支,然后删除 fixBug 分支。

分支命令

新建分支

在需要新的分支的时候,我们使用如下命令:

git branch newBranch       //基于当前分支创建新分支newBranch
git checkout -b newBranch  //创建新分支newBranch并切换到newBranch

git checkout -b develop 为例,此时我们的 commit 图变成了这样:

git 会创建一个 develop 指针指向 master 指向的 commit,并将 HEAD 指针指向 develop,表示当前工作区在 develop 分支下。


切换分支

我们需要切换分支的时候,使用 git checkout 命令:

git checkout develop  //切换到develop分支

切换分支的时候,git 会将 HEAD 指针指向你切换到的分支。


合并分支

当两个分支需要合并的时候,例如现在是这个样子的:

而我们想要在 master 分支上合并 develop 分支

git checkout master        //切换到master分支
git merge develop --no-ff  //合并develop到当前分支

此时,commit list 变成了这样:

关于 --no-ff 参数

这个参数是“不使用快速合并”的意思。去掉 --no-ff 参数,如果 master 需要合并的 develop 分支的父节点,也就是本例所示,会进行快速合并操作:即直接将 master 指针指向 develop 当前的 commit,没有留下分支合并的记录。如下图:

而使用了 --no-ff 参数的分支合并,会忠实地记录每一次分支合并信息。因此个人倾向一直使用 git merge {branch} --no-ff 进行分支合并。


分支删除

当想要删除某一分支的时候,使用 git branch -d {branchName}

git branch -d fixBug    //删除fixBug分支