Git特性分支工作流程
当你掌握了GIT中心式工作流程后,添加特性分支到开发过程中就非常容易,能够鼓励开发人员之间的协同并简化他们之间的沟通成本。
特性分支工作流程的核心思想是所有的特性开发工作等应该在一个专门的分支里进行,而不应该是在master分支里。这个封装让多名开发人员在一个特性上同时开发时能够轻松应对,而且不用在开发完成前向代码库提交代码。也让master分支永远不会包含不完整的代码,这对持续集成来说意义非凡。
特性封装开发方式可以巧用“拉取请求”围绕分支发起讨论,该方式允许其他开发人员在该特性上签署自己的意见,然后才把该分支集成到主分支上。或者是开发人员在开发中途感到困惑,可以开启一个“拉取请求”向你的队友寻求建议,“拉取请求”使团队成员在他人的工作上进行评论超级容易。
它是如何工作的
特性分支工作流程仍然使用中心式代码仓库,master分支仍然代表正式的项目历史记录。不过不同于以往直接在本地master分支上提交代码,开发者开始在新特性上工作时需要创建一个新分支,该特性分支有一个意义明确的名字,比如animated-menu-items或者issue-#1061,主要目的是让分支的目标一目了然。
Git的master分支和特性分支之间没有任何技术上的差别,因此开发人员可以对特性分支进行任何edit、stage、commit操作,就像在中心式工作流程一样。
另外,特性分支应当被推送到中心库,这就使开发人员能够共享特性代码而不影响正式代码。maste是中心代码库唯一“特殊”的分支,在中心库保存几个特性分支不会造成任何问题,而且这样做也是备份开发人员本地提交记录的有效方法。
拉取请求
撇开特性开发分离不说,分支也便于利用“拉取请求”对变更进行讨论,一旦某人完成了特性,必须要立马合并到master里,相反可以把特性分支push到中心库并且打开一个“拉取请求”,要求其他人合并自己的内容到master,这样就有机会在把这个特性并入住代码库之前对其变更进行评审。
代码评审是“拉取请求”的一个关键优势,不过这个功能的真实目的是用来讨论代码的,可以把“拉取请求”当作是对特定分支提供的讨论,这样话该功能在开发过程中就变得更加易用了。比如,如果一个开发人员想要在某个特定分支上获得帮助,他只需要开启一个“拉取请求”,感兴趣的当事人会收到一个通知,他们能够在相关提交的后面看到那个开发人员发起的问题。
一旦一个“拉取请求”被接受,发布特性的实际操作跟中心式工作流没有什么两样。首先需要确保本地master跟中心库的master保持同步,其次合并这个分支到master中并把更新后的master推送回中心库。
“拉取请求”的能力被一些代码管理产品增强了,比如Bitbucket或Stash,可以看看Stash的“拉取请求”文档上的相关说明。
示例
下面的示例演示了一个用于代码评审的“拉取请求”,不过请牢记“拉取请求”还能完成许多其它的目的。
Mary开始了一个新特性
在开发该特性之前,Mary需要一个独立里的分支在完成该特性,她用如下命令创建了一个新分支:
git checkout -b marys-feature master
本操作基于master分支派生了一个叫做marys-feature的分支,选项 -b 告知Git在该分支尚不存在时创建一个。在这个分支上,Mary跟往常一样进行edit、stage和commit等操作,提交了大量必要的变更来建设这个特性:
git status
git add <some-file>
git commit
Mary去吃午餐了
Mary在上午对她的特性添加了几个提交,她想在吃午饭前把这个特性分支推到中心仓库。这样能够备份上午的工作,不过Mary正在和其他开发人员协作,提交后其他开发人员就能访问到她的这些提交记录了。
git push -u origin marys-feature
该命令将分支marys-feature推送到中心仓库(origin),选项 -u 将该分支当作一个远程可跟踪分支,设置这个跟踪分支后,Mary可以调用没有任何参数的git push推送她的特性。
Mary完成了本特性
吃完午饭后,Mary完成了这个特性,在合并到master之前,她需要发起一个“拉取请求”让其他团队成员知道她做完了。不过她首先要确保中心库已经保存了最近的一些提交记录:
git push
然后她在自己的Git工具界面里创建了一个“拉取请求”准备合并marys-feature分支到master中,而其他成员会被自动通知到。“拉取请求”之所以非常不错,是因为它能够把注释说明显示在紧邻跟他人关联的提交之后,因此就非常容易针对具体的变更提出问题。
Bill收到了“拉取请求”
Bill收到了“拉取请求”并看了看marys-feature,他决定在把该分支集成到正式项目之前做一些改动,他和Mary使用“拉取请求”交流了几个来回。
Mary进行修改
Mary跟之前做的那样对这个特性分支进行edit、stage、commit操作,然后把更新推送到中心库,所有这些活动都在“拉取请求”中显示出来,Bill仍然能对它们添加注释。
只要Bill愿意,他就能拉取marys-feature到其本地代码库,并在上面工作,他添加的任何提交都会在“拉取请求”中显示。
Mary publishes her feature
一旦Bill接受了这些“拉取请求”,就需要有人(Bill或Mary)将这个特性分支合并到正式的项目中:
git checkout master
git pull
git pull origin marys-feature
git push
首先,任何执行合并操作的人都需要检出master分支并确保它是最新的;然后git pull origin marys-feature合并中心代码库的marys-feature的副本。也可以使用简单的git merge marys-feature命令,不过上面的命令能够确保总是拉取到最新版本的特性分支。最后,更新后的master需要被推送回origin。
这个操作过程总是产生一个合并提交,一些开发人员喜欢这样做,因为它就像是一个符号,表示特性加入乐代码库。如果你偏爱线性历史记录,可以将这个特性rebase到master分支的顶端,再执行合并操作,这回产生一个fast-forward合并。
一些GIT工具会通过允许上面的命令来自动化接受“拉取请求”的过程,你要做的只是点击“接受”按钮,即使你不这样做,它也至少能够在特性分支合并到master时自动关闭“拉取请求”。
同时,Jhon在做同样的事情
在Mary和Bill在marys-feature分支上工作、在她的“拉取请求”上讨论时,Jhon也同时在自己的分支上做同样的事情。通过把特性分离成独立的分支,每个人都能互不依赖地进行工作,不过,在开发人员之间还是会有一些必要的变更共享行为的。
何去何从
到目前为止,希望你至少能够从字面意思上理解了特性分支流程,它利用中心式工作流程,但是提供了数倍于单一master分支功能的工作方式。另外,特性分支也使“拉取请求”功能更加容易,它使开发人员在自己的版本控制工具里就能够讨论具体的提交结果。
特性分支工作流让开发项目的方式变得更加灵活,问题时有时候它太灵活了,对大的团队来说,赋予不同的分支更明确的职责更有好处,Gitflow工作流程就是一个管理特性开发、发布准备和日常维护的常用模式。