Git版本控制系統(tǒng)因?yàn)槠淇焖佟⒎植际?、輕量的多分支模型等優(yōu)點(diǎn),現(xiàn)在正在逐步取代SVN等集中式版本控制系統(tǒng)。
講道理的話,git的命令其實(shí)挺多的,而且底層的文件模型其實(shí)挺復(fù)雜的,但是一旦熟練使用的話,靈活、快速這些特點(diǎn)就不必說了,很多時(shí)候更有化腐朽為神奇的能力??梢赃@么說,如果你熟悉git的話,那么你玩起來得心應(yīng)手,如果你不熟悉的話,那么就是它玩你了。不過話說回來,團(tuán)隊(duì)協(xié)作中,往往不會(huì)用到很多高級(jí)的特性(比如cherry-pick、rebase、壓縮歷史、拆分提交等等),而是制定一套簡單高效的規(guī)范,然后大家都去follow這個(gè)規(guī)范即可。
git自帶一套多分支工作流機(jī)制,名為gitflow,在命令行中可以git help workflow
查看更加詳細(xì)的機(jī)制。那么問題來了,什么gitflow?
gitflow是構(gòu)建在Git之上的一個(gè)組織軟件開發(fā)活動(dòng)的模型,是在Git之上構(gòu)建的一項(xiàng)軟件開發(fā)最佳實(shí)踐。gitflow是一套使用Git進(jìn)行源代碼管理時(shí)的一套行為規(guī)范和簡化部分Git操作的工具。
說的直白點(diǎn),其實(shí)gitflow就是基于git規(guī)定了一些規(guī)范,要求在開發(fā)過程中,按照它定義的玩法來玩即可。一般而言,軟件開發(fā)模型有常見的瀑布模型、迭代開發(fā)模型、以及敏捷開發(fā)模型等不同的模型。每種模型有各自應(yīng)用場景。Git Flow重點(diǎn)解決的是由于源代碼在開發(fā)過程中的各種沖突導(dǎo)致開發(fā)活動(dòng)混亂的問題。因此,Git flow可以很好的于各種現(xiàn)有開發(fā)模型相結(jié)合使用。
社區(qū)中,有一個(gè)比較成功的gitflow模型,如下圖所示,
利用Git創(chuàng)建和管理分支的能力,為每個(gè)分支設(shè)定具有特定的含義名稱,并將軟件生命周期中的各類活動(dòng)歸并到不同的分支上。實(shí)現(xiàn)了軟件開發(fā)過程不同操作的相互隔離。
關(guān)于這個(gè)模型網(wǎng)上有很多的解釋,這里也給出了原作者的文章鏈接,有興趣的可以自己去研讀一下。我這里就不做過多解釋了,但是不可否認(rèn)這個(gè)思路無疑是非常棒的。
言歸正傳,其實(shí)這個(gè)gitflow模型還是挺復(fù)雜的,在實(shí)際中的開發(fā)團(tuán)隊(duì)中,完全照搬這套機(jī)制的還是比較少的,大部分都是以之為指導(dǎo),在其基礎(chǔ)之上做了一些增減。
組里面在上周的周會(huì)中,大家集中頭腦風(fēng)暴了gitflow這塊的內(nèi)容。大家雖然在細(xì)節(jié)上的觀點(diǎn)不一致,但是基本上都認(rèn)為應(yīng)該以其為指導(dǎo),從最精簡的模型上手。
下面是這張圖是最終的討論后的結(jié)果,
1,有特殊含義的分支只有三種:master、release、feature。master分支為主干,其含義是master分支代碼就是線上跑的代碼;release分支為發(fā)布分支,它會(huì)承載功能發(fā)布、QA回歸等流程;feature分支為功能分支,它承載了具體的功能開發(fā),所有的開發(fā)者都將基于feature分支簽出自己的個(gè)人開發(fā)分支。
2,從master簽出的分支只能是release和feature分支,master上的改動(dòng)必然都是來自release分支。換句話說,除了release分支,其他的所有類型的分支都不允許直接合并到master分支。這一點(diǎn)是強(qiáng)硬要求,否則無法保證master分支的代碼質(zhì)量。言下之意,master上的代碼都是來自release分支,而release分支都是經(jīng)過QA回歸過,有質(zhì)量把關(guān)的。
3,master、release、feature這三個(gè)分支的簽出與合并都由一個(gè)人來操作,其他人沒有操作權(quán)限。我們把這個(gè)人稱之為pudge,屠夫的意思,因?yàn)槎际峭ㄟ^pudge切割出來一個(gè)個(gè)核心分支。一般pudge還有一個(gè)backup。
4,當(dāng)有開發(fā)任務(wù)過來時(shí),pudge按照具體的業(yè)務(wù)從當(dāng)前的master分支簽出帶有業(yè)務(wù)標(biāo)識(shí)的feature分支,比如feature-finds-20161212
,同時(shí)分支會(huì)帶有時(shí)間戳來表達(dá)此分支大致的生命周期。
5,具體的開發(fā)人員按照自己的工種和定位,從feature-finds-20161212
上簽出自己的開發(fā)分支,我們稱之為RD分支。即圖中的RD1,RD2,RD3分支。RD分支一般而已都是相互獨(dú)立的,分支名不作要求。因?yàn)槌碎_發(fā)者自己,其他人理論上是不會(huì)關(guān)注某一個(gè)具體的RD分支的。當(dāng)然,同一個(gè)feature分支上可以簽出多個(gè)RD分支,環(huán)境相互隔離。
6,經(jīng)過一段時(shí)間的開發(fā)后,RD分支完成自己的開發(fā)任務(wù)了,開發(fā)者要主動(dòng)將自己的RD分支合并至feature分支。這個(gè)合并過程中,在不同的場景下,可能會(huì)有一些額外的操作。比如RD分支游離的時(shí)間過長,開發(fā)者可以先同步feature分支到自己的RD分支,然后再合并。開發(fā)者也可以在合并的時(shí)候走M(jìn)erge Request流程,將Code Reviewer指定為他人或自己。理論上MR在此環(huán)節(jié)的合并不作強(qiáng)硬要求。
7,RD分支合并進(jìn)feature分支之后,通過測試人員針對feature分支進(jìn)行QA。也就說,測試人員只關(guān)注feature分支,其他的RD分支不需要care。
8,若測試在feature上QA時(shí)發(fā)現(xiàn)有問題,通過相關(guān)的開發(fā)去修復(fù)。開發(fā)在自己的RD分支進(jìn)行bugfix,完畢后再次合并到feature。通知測試人員進(jìn)行回歸。
9,若feature分支的測試無問題,確定可以上線。此時(shí)通知pudge從master簽出帶有日期版本號(hào)的release分支,然后通過Merge Request將feature分支合并進(jìn)release分支。這一步有兩個(gè)關(guān)鍵點(diǎn),一個(gè)是由pudge從master簽出release分支,另一個(gè)是由pudge來操作feature分支通過MR的方式合并進(jìn)release分支。此外,當(dāng)某一個(gè)release節(jié)點(diǎn)需要同時(shí)發(fā)布多個(gè)feature分支,那我們就針對多個(gè)feature分支重復(fù)7,8,9。
10,測試人員在release分支上進(jìn)行回歸。若無問題,即對release分支走上線流程(注意:這里是對release而不是master)。上線完畢,由pudge將release分支合并進(jìn)master。若release的回歸出現(xiàn)問題,則重復(fù)8,9。
11,若需要緊急處理線上問題或者一些小問題,比如文案修復(fù)之類的。由pudge從master簽出release分支,通知相關(guān)開發(fā)人員評估工作量,能否直接在release上修改,還是需要走更多的分支流程,靈活處理。
主要的流程和場景如上所述,應(yīng)該條理還是比較清晰的。所有的流程中,有一個(gè)關(guān)鍵角色,就是pudge?;旧虾诵姆种У暮灣?、合并、MR操作都是由這個(gè)人來完成。其他的開發(fā)和測試,只需要關(guān)注自己需要關(guān)心的分支即可,其他的不用關(guān)注。在具體的開發(fā)工作中,若遇到一些不太好處理的分支操作,也都交由pudge來處理。
更多建議: