1 TBD(Trunk Based Development)
Trunk Based Development早在svn時(shí)代就已經(jīng)流行,是種比較簡(jiǎn)單的分支管理模型。
典型的TBD模型如下:

特點(diǎn):
他只有一個(gè)主干分支
每個(gè)人寫完代碼自測(cè)通過后就往主干上面Push,要發(fā)布的時(shí)候就拉個(gè)Release分支。
優(yōu)點(diǎn):
對(duì)持續(xù)集成友好。
缺點(diǎn):
多個(gè)人開發(fā)多個(gè)功能時(shí)代碼干擾比較嚴(yán)重;
如果臨上線前發(fā)現(xiàn)有問題,剔除代碼比較困難;
即使沒有需求變更要下掉代碼,有些提交如果未能達(dá)到上線標(biāo)準(zhǔn),需要加Feature Toggle來控制打開關(guān)閉。這是一個(gè)需要平衡的事情,往往會(huì)增加一定開發(fā)成本和風(fēng)險(xiǎn);
適用:
因相對(duì)簡(jiǎn)單,難以應(yīng)對(duì)復(fù)雜情況,適用用于小型項(xiàng)目
2 功能分支協(xié)同工作流
上面的那種方式有一個(gè)問題,就是大家都在一個(gè)主干上開發(fā)程序,對(duì)于小團(tuán)隊(duì)或是小項(xiàng)目你可以這么干,但是對(duì)比較大的項(xiàng)目或是人比較多的團(tuán)隊(duì),這么干就會(huì)有很多問題。
最大的問題就是代碼可能干擾太嚴(yán)重。尤其是,我們想安安靜靜地開發(fā)一個(gè)功能時(shí),我們想把各個(gè)功能的代碼變動(dòng)隔離開來,同時(shí)各個(gè)功能又會(huì)有多個(gè)開發(fā)人員在開發(fā)。
這時(shí),我們不想讓各個(gè)功能的開發(fā)人員都在 Master 分支上共享他們的代碼。我們想要的協(xié)同方式是這樣的:同時(shí)開發(fā)一個(gè)功能的開發(fā)人員可以分享各自的代碼,但是不會(huì)把代碼分享給開發(fā)其他功能的開發(fā)人員,直到整個(gè)功能開發(fā)完畢后,才會(huì)分享給其他的開發(fā)人員(也就是進(jìn)入主干分支)。
因此,我們引入“功能分支”,如下:

就像上面這個(gè)圖顯示的一樣,紫色的分支就是功能分支,合并后就會(huì)像上面這個(gè)樣子。
3 GitFlow 協(xié)同工作流
在真實(shí)的生產(chǎn)過程中,前面的協(xié)同工作流還是不能滿足工作的要求。這主要因?yàn)槲覀兊纳a(chǎn)過程是比較復(fù)雜的,軟件生產(chǎn)中會(huì)有各式各樣的問題,并要面對(duì)不同的環(huán)境。我們要在不停地開發(fā)新代碼的同時(shí),維護(hù)線上的代碼,于是,就有了下面這些需求。
希望有一個(gè)分支是非常干凈的,上面是可以發(fā)布的代碼,上面的改動(dòng)永遠(yuǎn)都是可以發(fā)布到生產(chǎn)環(huán)境中的。這個(gè)分支上不能有中間開發(fā)過程中不可以上生產(chǎn)線的代碼提交。
希望當(dāng)代碼達(dá)到可以上線的狀態(tài)時(shí),也就是在 alpha/beta release 時(shí),在測(cè)試和交付的過程中,依然可以開發(fā)下一個(gè)版本的代碼。
最后,對(duì)于已經(jīng)發(fā)布的代碼,也會(huì)有一些 Bug-fix 的改動(dòng),不會(huì)將正在開發(fā)的代碼提交到生產(chǎn)線上去。
你看,面對(duì)這些需求,前面的那些協(xié)同方式就都不行了。因?yàn)槲覀儾粌H是要在整個(gè)團(tuán)隊(duì)中共享代碼,我們要的更是管理好不同環(huán)境下的代碼不互相干擾。說得技術(shù)一點(diǎn)兒就是,要管理好代碼與環(huán)境的一致性。
為了解決這些問題,GitFlow 協(xié)同工作流就出來了。
GitFlow 協(xié)同工作流是由 Vincent Driessen 于 2010 年在 A successful Git branching model 這篇文章介紹給世人的。
這個(gè)協(xié)同工作流的核心思想如下圖所示。

整個(gè)代碼庫中一共有五種分支。
Master 分支。也就是主干分支,用作發(fā)布環(huán)境,上面的每一次提交都是可以發(fā)布的。
Feature 分支。也就是功能分支,用于開發(fā)功能,其對(duì)應(yīng)的是開發(fā)環(huán)境。
Developer 分支。是開發(fā)分支,一旦功能開發(fā)完成,就向 Developer 分支合并,合并完成后,刪除功能分支。這個(gè)分支對(duì)應(yīng)的是集成測(cè)試環(huán)境。
Release 分支。當(dāng) Developer 分支測(cè)試達(dá)到可以發(fā)布狀態(tài)時(shí),開出一個(gè) Release 分支來,然后做發(fā)布前的準(zhǔn)備工作。這個(gè)分支對(duì)應(yīng)的是預(yù)發(fā)環(huán)境。之所以需要這個(gè) Release 分支,是我們的開發(fā)可以繼續(xù)向前,不會(huì)因?yàn)橐l(fā)布而被 block 住而不能提交。
一旦 Release 分支上的代碼達(dá)到可以上線的狀態(tài),那么需要把 Release 分支向 Master 分支和 Developer 分支同時(shí)合并,以保證代碼的一致性。然后再把 Release 分支刪除掉。
Hotfix 分支。是用于處理生產(chǎn)線上代碼的 Bug-fix,每個(gè)線上代碼的 Bug-fix 都需要開一個(gè) Hotfix 分支,完成后,向 Developer 分支和 Master 分支上合并。合并完成后,刪除 Hotfix 分支。
這就是整個(gè) GitFlow 協(xié)同工作流的工作過程。我們可以看到:
我們需要長期維護(hù) Master 和 Developer 兩個(gè)分支。
這其中的方式還是有一定復(fù)雜度的,尤其是 Release 和 Hotfix 分支需要同時(shí)向兩個(gè)分支作合并。所以,如果沒有一個(gè)好的工具來支撐的話,這會(huì)因?yàn)槲覀兛赡軙?huì)忘了做一些操作而導(dǎo)致代碼不一致。
GitFlow 協(xié)同雖然工作流比較重。但是它幾乎可以應(yīng)對(duì)所有公司的各種開發(fā)流程,包括瀑布模型,或是快速迭代模型。
優(yōu)點(diǎn):
可以解決實(shí)績生產(chǎn)過程中各種復(fù)雜的問題;
缺點(diǎn):
因?yàn)榉种?,所以?huì)出現(xiàn) git log 混亂的局面
在開發(fā)得足夠快的時(shí)候,你會(huì)覺得同時(shí)維護(hù) Master 和 Developer 兩個(gè)分支是一件很無聊的事,因?yàn)檫@兩個(gè)分支在大多數(shù)情況下都是一樣的。包括 Release 分支,你會(huì)覺得創(chuàng)建的這些分支太無聊
整個(gè)開發(fā)過程也會(huì)因?yàn)檫@么復(fù)雜的管理變得非常復(fù)雜。尤其當(dāng)你想回滾某些人的提交時(shí),你就會(huì)發(fā)現(xiàn)這事似乎有點(diǎn)兒不好干了。而且在工作過程中,你會(huì)來來回回地切換工作的分支,有時(shí)候一不小心沒有切換,就提交到了不正確的分支上,你還要回滾和重新提交,等等
GitLab 一開始是 GitFlow 的堅(jiān)定支持者,后來因?yàn)檫@些吐槽,以及 Hacker News 和 Reddit 上大量的討論,GitLab 也開始不玩了。他們寫了一篇 blog來創(chuàng)造了一個(gè)新的 Workflow——GitLab Flow,這個(gè) GitLab Flow 是基于 GitHub Flow 來做的
4 GitHub Flow
所謂 GitHub Flow,其實(shí)也叫 Forking flow,也就是 GitHub 上的那個(gè)開發(fā)方式。
每個(gè)開發(fā)人員都把“官方庫”的代碼 fork 到自己的代碼倉庫中。
然后,開發(fā)人員在自己的代碼倉庫中做開發(fā),想干啥干啥。
因此,開發(fā)人員的代碼庫中,需要配兩個(gè)遠(yuǎn)程倉庫,一個(gè)是自己的庫,一個(gè)是官方庫(用戶的庫用于提交代碼改動(dòng),官方庫用于同步代碼)。
然后在本地建“功能分支”,在這個(gè)分支上做代碼開發(fā)。
這個(gè)功能分支被 push 到開發(fā)人員自己的代碼倉庫中。
然后,向“官方庫”發(fā)起 pull request,并做 Code Review。
一旦通過,就向官方庫進(jìn)行合并。
這就是 GitHub 的工作流程。
如果你有“官方庫”的權(quán)限,那么就可以直接在“官方庫”中建功能分支開發(fā),然后提交 pull request。通過 Code Review 后,合并進(jìn) Master 分支,而 Master 一旦有代碼被合并就可以馬上 release。
這是一種非常 Geek 的玩法。這需要一個(gè)自動(dòng)化的 CI/CD 工具做輔助。是的,CI/CD 應(yīng)該是開發(fā)中的標(biāo)配了。
GithubFlow 模式,不過這種策略無非是在 TBD的基礎(chǔ)上,增加了個(gè)人倉庫和 Pull Request 合并代碼的操作,與在同一個(gè)倉庫里增加個(gè)人分支的做法類似,從實(shí)用的意義來說,它更合適分布式團(tuán)隊(duì)。
5 GitLab Flow
然而,GitHub Flow 這種玩法依然會(huì)有好多問題,因?yàn)槠潆m然變得很簡(jiǎn)單,但是沒有把我們的代碼和我們的運(yùn)行環(huán)境給聯(lián)系在一起。所以,GitLab 提出了幾個(gè)優(yōu)化點(diǎn)。
其中一個(gè)是引入環(huán)境分支,如下圖所示,其包含了預(yù)發(fā)布(Pre-Production)和生產(chǎn)(Production)分支。

而有些時(shí)候,我們還會(huì)有不同版本的發(fā)布,所以,還需要有各種 release 的分支。如下圖所示。Master 分支是一個(gè) roadmap 分支,然后,一旦穩(wěn)定了就建穩(wěn)定版的分支,如 2.3.stable 分支和 2.4.stable 分支,其中可以 cherry-pick master 分支上的一些改動(dòng)過去。

這樣也就解決了兩個(gè)問題:
環(huán)境和代碼分支對(duì)應(yīng)的問題;
版本和代碼分支對(duì)應(yīng)的問題。
6 阿里AoneFlow
阿里有很多的研發(fā)團(tuán)隊(duì),不同事業(yè)部使用的發(fā)布流程、分支策略并非整齊劃一,但總體上看是比較規(guī)整的。其中有一種主流的發(fā)布模式以及對(duì)應(yīng)的分支使用方式,稱為“AoneFlow”。
在 AoneFlow 上你能看到許多其他分支模式的影子。它基本上兼顧了 TrunkBased 的“易于持續(xù)集成”和 GitFlow 的“易于管理需求”特點(diǎn),同時(shí)規(guī)避掉 GitFlow 的那些繁文縟節(jié)。
看一下具體套路。AoneFlow 只使用三種分支類型:主干分支、特性分支、發(fā)布分支,以及三條基本規(guī)則。
規(guī)則一,開始工作前,從主干創(chuàng)建特性分支。
AoneFlow 的特性分支基本借鑒 GitFlow,沒有什么特別之處。每當(dāng)開始一件新的工作項(xiàng)(比如新的功能或是待解決的問題)的時(shí)候,從代表最新已發(fā)布版本的主干上創(chuàng)建一個(gè)通常以feature/前綴命名的特性分支,然后在這個(gè)分支上提交代碼修改。也就是說,每個(gè)工作項(xiàng)(可以是一個(gè)人完成,或是多個(gè)人協(xié)作完成)對(duì)應(yīng)一個(gè)特性分支,所有的修改都不允許直接提交到主干。

規(guī)則二,通過合并特性分支,形成發(fā)布分支。
AoneFlow 的發(fā)布分支設(shè)計(jì)十分巧妙,可謂整個(gè)體系的精髓。GitFlow 先將已經(jīng)完成的特性分支合并回公共主線(即開發(fā)分支),然后從公共主線拉出發(fā)布分支。TrunkBased 同樣是等所有需要的特性都在主干分支上開發(fā)完成,然后從主干分支的特定位置拉出發(fā)布分支。而 AoneFlow 的思路是,從主干上拉出一條新分支,將所有本次要集成或發(fā)布的特性分支依次合并過去,從而得到發(fā)布分支。發(fā)布分支通常以release/前綴命名。
這條規(guī)則很簡(jiǎn)單,不過實(shí)際的玩法就相當(dāng)豐富了。

首先,發(fā)布分支的用途可以很靈活。基礎(chǔ)玩法是將每條發(fā)布分支與具體的環(huán)境相對(duì)應(yīng),比如release/test分支對(duì)應(yīng)部署測(cè)試環(huán)境,release/prod分支對(duì)應(yīng)線上正式環(huán)境等等,并與流水線工具相結(jié)合,串聯(lián)各個(gè)環(huán)境上的代碼質(zhì)量掃描和自動(dòng)化測(cè)試關(guān)卡,將產(chǎn)出的部署包直接發(fā)布到相應(yīng)環(huán)境上。進(jìn)階點(diǎn)的玩法是將一個(gè)發(fā)布分支對(duì)應(yīng)多個(gè)環(huán)境,比如把灰度發(fā)布和正式發(fā)布串在一起,中間加上人工驗(yàn)收的步驟。高級(jí)的玩法呢,要是按迭代計(jì)劃來關(guān)聯(lián)特性分支,創(chuàng)建出以迭代演進(jìn)的固定發(fā)布分支,再把一系列環(huán)境都串在這個(gè)發(fā)布分支的流水線上,就有點(diǎn)經(jīng)典持續(xù)集成流水線的味道了。再或者做一個(gè)將所有特性分支都關(guān)聯(lián)在一起的發(fā)布分支,專門用于對(duì)所有提交做集成測(cè)試,就玩出了 TrunkBased 的效果。當(dāng)然,這些花哨的高級(jí)玩法是我臆想的,阿里的發(fā)布分支一般都還是比較中規(guī)中矩。
其次,發(fā)布分支的特性組成是動(dòng)態(tài)的,調(diào)整起來特別容易。在一些市場(chǎng)瞬息萬變的互聯(lián)網(wǎng)企業(yè),以及采用“敏捷運(yùn)作”的乙方企業(yè)經(jīng)常會(huì)遇到這種情況,已經(jīng)完成就等待上線的需求,隨時(shí)可能由于市場(chǎng)策略調(diào)整或者甲方的一個(gè)臨時(shí)決定,其中某個(gè)功能忽然要求延遲發(fā)布或者干脆不要了。再或者是某個(gè)特性在上線前發(fā)現(xiàn)存在嚴(yán)重的開發(fā)問題,需要排除。按往常的做法,這時(shí)候就要來手工“剔代碼”了,將已經(jīng)合并到開發(fā)分支或者主干分支的相關(guān)提交一個(gè)個(gè)剔除出去,做過的同學(xué)都知道很麻煩。在 AoneFlow 的模式下,重建發(fā)布分支只是分分鐘的事,將原本的發(fā)布分支刪掉,從主干拉出新的同名發(fā)布分支,再把需要保留的各特性分支合并過來就搞定。這一系列動(dòng)作能夠在很大程度上實(shí)現(xiàn)自動(dòng)化,而且不會(huì)在倉庫留下一堆剔除代碼的記錄,干凈無污染。
此外,發(fā)布分支之間是松耦合的,這樣就可以有多個(gè)集成環(huán)境分別進(jìn)行不同的特性組合的集成測(cè)試,也能方便的管理各個(gè)特性進(jìn)入到不同環(huán)境上部署的時(shí)機(jī)。松耦合并不代表沒有相關(guān)性,由于測(cè)試環(huán)境、集成環(huán)境、預(yù)發(fā)布環(huán)境、灰度環(huán)境和線上正式環(huán)境等發(fā)布流程通常是順序進(jìn)行的,在流程上可以要求只有通過前一環(huán)境驗(yàn)證的特性,才能傳遞到下一個(gè)環(huán)境做部署,形成漏斗形的特性發(fā)布流。阿里有統(tǒng)一平臺(tái)來自動(dòng)化完成特性組合在發(fā)布分支間的遷移,在下面講工具的部分里會(huì)再介紹。
規(guī)則三,發(fā)布到線上正式環(huán)境后,合并相應(yīng)的發(fā)布分支到主干,在主干添加標(biāo)簽,同時(shí)刪除該發(fā)布分支關(guān)聯(lián)的特性分支。
當(dāng)一條發(fā)布分支上的流水線完成了一次線上正式環(huán)境的部署,就意味著相應(yīng)的功能真正的發(fā)布了,此時(shí)應(yīng)該將這條發(fā)布分支合并到主干。為了避免在代碼倉庫里堆積大量歷史上的特性分支,還應(yīng)該清理掉已經(jīng)上線部分特性分支。與 GitFlow 相似,主干分支上的最新版本始終與線上版本一致,如果要回溯歷史版本,只需在主干分支上找到相應(yīng)的版本標(biāo)簽即可。

除了基本規(guī)則,還有一些實(shí)際操作中不成文的技巧。比如上線后的 Hotfix,正常的處理方法應(yīng)該是,創(chuàng)建一條新的發(fā)布分支,對(duì)應(yīng)線上環(huán)境(相當(dāng)于 Hotfix 分支),同時(shí)為這個(gè)分支創(chuàng)建臨時(shí)流水線,以保障必要的發(fā)布前檢查和冒煙測(cè)試能夠自動(dòng)執(zhí)行。但其實(shí)還有一種簡(jiǎn)便方法是,將線上正式環(huán)境對(duì)應(yīng)的發(fā)布分支上關(guān)聯(lián)的特性分支全部清退掉,在這個(gè)發(fā)布分支上直接進(jìn)行修改,改完利用現(xiàn)成的流水線自動(dòng)發(fā)布。如果非得修一個(gè)歷史版本的 Bug 怎么辦呢?那就老老實(shí)實(shí)的在主干分支找到版本標(biāo)簽位置,然后從那個(gè)位置創(chuàng)建 Hotfix 分支吧,不過由于阿里的產(chǎn)品大多是線上 SaaS 業(yè)務(wù),這樣的場(chǎng)景并不多見。
正是這些簡(jiǎn)單的規(guī)則,組成了 AoneFlow 獨(dú)樹一幟的核心套路。
AoneFlow 中每一個(gè)看似簡(jiǎn)單的步驟都并非憑空臆造,而是經(jīng)歷大量產(chǎn)品團(tuán)隊(duì)反復(fù)磨礪后積累下來的經(jīng)驗(yàn)。接下來,我會(huì)說說 AoneFlow 的技術(shù)門檻以及阿里內(nèi)部的應(yīng)對(duì)之道。
思考總結(jié),目前使用AoneFlow
總結(jié)下就是各種git工作流都是 功能分支 + 長期分支 構(gòu)成。
目前公司使用的協(xié)同工作流是基于AoneFlow而來,也有些GitFlow的身影。也符合AoneFlow的三個(gè)規(guī)則:
開始工作前,從主干創(chuàng)建特性分支
通過合并特性分支,形成發(fā)布分支
發(fā)布到線上正式環(huán)境后,合并相應(yīng)的發(fā)布分支到主干,在主干添加標(biāo)簽,同時(shí)刪除該發(fā)布分支關(guān)聯(lián)的特性分支
有如下分支:
master分支:(長期存在)master分支上的代碼一定是已經(jīng)發(fā)到生產(chǎn)環(huán)境的代碼,可能會(huì)稍有延遲(發(fā)到release分支的代碼不一定馬上合到master)。
test分支:(長期存在)相當(dāng)于gitFlow中的develope分支,是集成測(cè)試環(huán)境分支,會(huì)包含各種開發(fā)中的功能。
pre_prod分支:(長期存在)預(yù)發(fā)環(huán)境分支,在線上生產(chǎn)環(huán)境代碼的基礎(chǔ)上加上本次需要發(fā)布的內(nèi)容。
release/master分支:(長期存在)線上生產(chǎn)環(huán)境分支。
release/canary分支:(長期存在)灰度環(huán)境分支
feature/feature01分支:功能分支,在發(fā)布后可以刪除。
hotfix分支:線上bug修復(fù)分支,其實(shí)和feature分支操作一樣,也是從master分支新建出來。
開發(fā)到發(fā)布的過程如下:
從master分支新建一個(gè)分支feature001;
開發(fā)一部分后或者開發(fā)完后feature合到test分支,如果提測(cè)了測(cè)試會(huì)在這個(gè)分支先測(cè)試;
測(cè)試完成如果有預(yù)發(fā)環(huán)境會(huì)發(fā)布到預(yù)發(fā)環(huán)境;
預(yù)發(fā)通過后會(huì)合并到發(fā)布分支release/v1.1分支,可能是多個(gè)feature分支都合過來;
release/v1.1分支合并到release/master分支,至此就發(fā)布到線上環(huán)境了。
如果發(fā)布完后沒有問題,release/master會(huì)合并會(huì)master(一般不會(huì)合并完成就馬上合,萬一要撤回呢-_-,個(gè)人習(xí)慣在每次新建feature分支的時(shí)候檢查下release/master是否比master新, 如果新的話就會(huì)合并回master分支)
bug修復(fù),在master分支新建hotfix/hotfix001,改完后合并到test分支,測(cè)試后合并到最新的release/v1.1分支上,或者新建release/v1.1_bugfix001分支, 然后再合并到release/master分支。 最后release/master合回master。
如果發(fā)布后有問題需要撤回怎么辦?
把release/master 回退到上次發(fā)布時(shí)間點(diǎn)的代碼,重新發(fā)布。
如果多個(gè)featuer分支同時(shí)開發(fā),但是一個(gè)分支對(duì)另一個(gè)分支有依賴關(guān)系怎么辦?
根據(jù)計(jì)劃發(fā)布順序來,如果feature1會(huì)先于feature2發(fā)布, 那feature2分支就從master新建然后把featuer1合并過來,盡量定期同步,可以避免很多的沖突,等feature1發(fā)布完合會(huì)master后,再把master分支合并到feature2分支。這樣可以確保feature2分支上是在線上環(huán)境代碼的基礎(chǔ)只有feature2的改動(dòng)。
協(xié)同工作流的本質(zhì)
此部分摘自陳皓的文章,覺得另辟蹊徑,是更深層次的思考,原文如下:
代碼的協(xié)同工作流屬于 SCM(Software Configuration Management)的范疇,要挑選好適合自己的方式,我們需要知道軟件工程配置管理的本質(zhì)。
根據(jù)這么多年來我在各個(gè)公司的經(jīng)歷,有互聯(lián)網(wǎng)的,有金融的,有項(xiàng)目的,有快速迭代的等,我認(rèn)為團(tuán)隊(duì)協(xié)同工作的本質(zhì)不外乎這么幾個(gè)事兒。
不同的團(tuán)隊(duì)能夠盡可能地并行開發(fā)。
不同軟件版本和代碼的一致性。
不同環(huán)境和代碼的一致性。
代碼總是會(huì)在穩(wěn)定和不穩(wěn)定間交替。我們希望生產(chǎn)線上的代碼總是能對(duì)應(yīng)到穩(wěn)定的代碼上來。
基本上述的四個(gè)事兒,上述的工作流大都是在以建立不同的分支,來做到開發(fā)并行、代碼和環(huán)境版本一致,以及穩(wěn)定的代碼。
要選擇適合自己的協(xié)同工作流,我們就不得不談一下軟件開發(fā)的工作模式。
首先,我們知道軟件開發(fā)的趨勢(shì)一定是下面這個(gè)樣子的。
以微服務(wù)或是 SOA 為架構(gòu)的方式。一個(gè)大型軟件會(huì)被拆分成若干個(gè)服務(wù),那么,我們的代碼應(yīng)該也會(huì)跟著服務(wù)拆解成若干個(gè)代碼倉庫。這樣一來,我們的每個(gè)代碼倉庫都會(huì)變小,于是我們的協(xié)同工作流程就會(huì)變簡(jiǎn)單。對(duì)于每個(gè)服務(wù)的代碼倉庫,我們的開發(fā)和迭代速度也會(huì)變得很快,開發(fā)團(tuán)隊(duì)也會(huì)跟服務(wù)一樣被拆分成多個(gè)小團(tuán)隊(duì)。這樣一來, GitFlow 這種協(xié)同工作流程就非常重了,而 GitHub 這種方式或是功能分支這種方式會(huì)更適合我們的開發(fā)。
以 DevOps 為主的開發(fā)流程。DevOps 關(guān)注于 CI/CD,需要我們有自動(dòng)化的集成測(cè)試和持續(xù)部署的工具。這樣一來,我們的代碼發(fā)布速度就會(huì)大大加快,每一次提交都能很快地被完整地集成測(cè)試,并很快地發(fā)布到生產(chǎn)線上。
于是,我們就可以使用更簡(jiǎn)單的協(xié)同工作流程,不需要維護(hù)多個(gè)版本,也不需要關(guān)注不同的運(yùn)行環(huán)境,只需要一套代碼,就可以了。GitHub Flow 或是功能分支這種方式也更適應(yīng)這種開發(fā)。
你看,如果我們將軟件開發(fā)升級(jí)并簡(jiǎn)化到 SOA 服務(wù)化以及 DevOps 上來,那么協(xié)同工作流就會(huì)變得非常簡(jiǎn)單。所以,協(xié)同工作流的本質(zhì),并不是怎么玩好代碼倉庫的分支策略,而是玩好我們的軟件架構(gòu)和軟件開發(fā)流程。
當(dāng)然,服務(wù)化和 DevOps 是每個(gè)開發(fā)團(tuán)隊(duì)需要去努力的目標(biāo),但就算是這樣,也有某些情況我們需要用重的協(xié)同工作的模式。比如,整個(gè)公司在做一個(gè)大的升級(jí)項(xiàng)目,這其中會(huì)對(duì)代碼做一個(gè)大的調(diào)整(很有可能是一次重大的重構(gòu))。
這個(gè)時(shí)候,可能還有一些并行的開發(fā)需要做,如一些小功能的優(yōu)化,一些線上 Bug 的處理,我們可能還需要在生產(chǎn)線上做新舊兩個(gè)版本的 A/B 測(cè)試。在這樣的情況下,我們可能會(huì)或多或少地使用 GitFlow 協(xié)同工作流。
但是,這樣的方式不會(huì)是常態(tài),是特殊時(shí)期,我們不可能隔三差五地對(duì)系統(tǒng)做架構(gòu)或是對(duì)代碼做大規(guī)模的重構(gòu)。所以,在大多數(shù)情況下,我們還是應(yīng)該選擇一個(gè)比較輕量的協(xié)同工作流,而在特殊時(shí)期特例特辦。
與其花時(shí)間在 Git 協(xié)同工作流上,還不如把時(shí)間花在調(diào)整軟件架構(gòu)和自動(dòng)化軟件生產(chǎn)和運(yùn)維流程上來,這才是真正簡(jiǎn)化協(xié)同工作流程的根本。
參考文章
陳皓 的《左耳聽風(fēng) 》- Git協(xié)同工作流,你該怎么選? ?