企業程式碼版本管理之爭:TrunkBased vs GitFlow vs AoneFlow vs OneFlow vs ExeFlow
目錄
- 引言
- TrunkBased
- GitFlow
- AoneFlow
- OneFlow
- ExeFlow
- 綜述
引言
網路上版本管理系統之爭持久而喧囂,依照聲量來講目前應該是Git佔了較大的優勢。不過我們本文的關注點在於程式碼的分支管理模型,因為大家無論是用SVN或者Git,目的是為了解決研發過程管理中的實際問題。我這裡整理幾種分支管理模型,這樣大家可以對照自己的痛點選擇合適的模型。不過並不是最靈活的方案就最好,靈活意味著分支的管理和具體研發學習曲線都更復雜。
我先根據實際生產過程中企業面臨的問題列出一個清單:
- 學習曲線(Complexity)
企業都希望研發團隊能夠快投入生產,而在版本管理這種“小事”不要花費太多精力。 - 需求變更(Release)
企業在一個迭代過程中是否能夠完全不進行需求的變更,無論你們的週期是兩週、一個月、或者一季度。 - 線上修正(Hotfix)
系統目前是否已經非常穩定,不存在需要釋出線上修正的可能。 - 多環境(CI/CD)
企業是否存在多環境的要求(測試、預釋出、正式等) - 長期需求(Long-Lived Version-control Story)
企業是否存在一個大需求可能要持續數個迭代。(例如底層的基礎業務模型擴充套件,增加新的資料隔離標識欄位,涉及到系統底層或者全系統業務邏輯的變更。這裡列這種需求並不是說必須支援,有些普通需求由於錯誤的技術方案/市場的變化等情況就會變化成這樣的需求,所以綜合考慮邊界情況。)
另外也交代一下我所在的公司背景:
我們是一家企業內部學習培訓的人力資源SAAS管理平臺,對於平臺改進有自己的規劃和目標,但是又面臨著大客戶的定製化需求以及交付時間壓力。技術棧還是Java和.Net 雙棧並存,所以可以說是最複雜的研發環境了。我們也慢慢衍生出了自己的一套改進的程式碼版本管理模型。
TrunkBased
原理1:研發團隊在名稱為 Trunk 的單一分支進行開發,當開發工作到一定階段的時候達到可釋出條件後,切出Release分支進行釋出,並且Release分支是不可以修改的僅僅做釋出使用。大部分SVN使用者是基於本模型進行開發。
適合小團隊的模型,大家都直接在Trunk上進行開發
適合較大團隊的模型,大家切出短期的特性分支進行開發,完成後合併回Trunk。
適用場景:適合於單一穩定產品線,迭代排期穩定,需求邊界完全可控的團隊。
優點:模型簡單
缺點:
- 線上修正:按照上圖目前系統已經發布了12.1,下一個迭代也在開發中,線上發現了問題。由於Release分支是禁止修改的,而Trunk此時包含了新的特性程式碼無法釋出,就造成了線上異常無法修復。
- 需求變更:無法支援,已經提交到Trunk的內容抽離很困難。
- 多環境:無法支援
- 長期需求:無法支援
總結:Trunk Based最大的優勢就是清晰簡單,付出的代價就是靈活性,基本可以說不存在任何靈活性。適用的場景我覺得是進入到後期維護的大型系統,不會做太多的變更並且不會有太多的突發問題。
GitFlow
GitFlow來源應該是 Vincent Driessen 在2010年1月發表的這篇《A successful Git branching model》,基本是現在Git中最出名的流程管理方法了。
這張圖相信大家都不陌生。
原理:
主要分為5個分支
- master分支存放所有正式釋出的版本,可以作為專案歷史版本記錄分支,不直接提交程式碼。僅用於保持一個對應線上執行程式碼的 code base。
- develop分支為主開發分支,一般不直接提交程式碼
- feature分支為新功能分支,feature分支都是基於develop建立的,開發完成後會合併到develop分支上。同時存在多個
- release分支基於最新develop分支建立,當新功能足夠釋出一個新版本(或者接近新版本釋出的截止日期),從develop分支建立一個release分支作為新版本的起點,用於測試,所有的測試bug在這個分支改。測試完成後合併到master並打上版本號,同時也合併到develop,更新最新開發分支。(一旦打了release分支之後不要從develop分支上合併新的改動到release分支),同一時間只有1個,生命週期很短,只是為了釋出。
- hotfix分支基於master分支建立,對線上版本的bug進行修復,完成後直接合併到master分支和develop分支,如果當前還有新功能release分支,也同步到release分支上。同一時間只有1個,生命週期較短。
適用場景:處於前中期的大型專案,人員較多管理場景較複雜,但是迭代相對穩定,週期內不會頻繁的變更需求,儘量不要開長需求分支。
優點:
能夠支援線上修正、多環境
缺點: - 複雜度稍高
- 需求變更:不夠靈活,由於主分支實際上是基於develop,那意味著一旦程式碼提交上去,一段時間後需要撤銷(本次迭代不釋出)就比較困難
總結:Gitflow已經很偏向網際網路風格的程式碼管理,考慮到了多環境、線上修正。而且現在很多IDE或者工具有整合了GitFlow的外掛使用起來會更簡單。對於有良好規劃和進度控制的專案,應該是已經夠用了。但是對於一些有交付日期的,但是需求池可以調整的專案可能還不夠靈活。
AoneFlow
阿里的研發效能事業部專家基於TrunkBased和GitFlow提出了一套新思路:AoneFlow。
原理:AoneFlow 只使用三種分支型別:主幹分支、特性分支、釋出分支,以及三條基本規則。
開始工作前,從主幹建立特性分支。
通過合併特性分支,形成釋出分支。
釋出到線上正式環境後,合併相應的釋出分支到主幹,在主幹新增標籤,同時刪除該釋出分支關聯的特性分支。
缺點:
- 複雜度稍高
- 多環境:由於沒有develop分支所以可能測試環境構建會有一些問題。
優點: - 線上環境,長期需求都是支援的
總結:AoneFlow最重要的點,就是保證master分支可用和隨時可釋出,其他可能都是臨時分支。所以取名的時候應該是Ali-One-Flow,這個含義。臨時分支的組裝就有很多種玩法了,需要企業根據自己的需要來定製處理。
OneFlow
OneFlow我找到兩個版本,一個是國內版本,一個是國外的版本。
國內版本:
原理:此模式是TrunkBased的升級版,增加了Hotfix分支,採用多主幹模式,一般是雙主幹(一個主幹分支+一個主幹釋出分支)。OneFlow在TrunkBased模式演進中,做了一此改善,分離了主幹分支和釋出分支,有效的規避了一些問題。但是同樣還不能滿足多版本,多產品的並行開發。
國外版本:
原理:此模式是GitFlow的簡化版本,但是(作者認為)並不比GitFlow遜色。主要也就是雙分支2,除了主幹分支,只會額外保持一個分支,在不同的階段切除特性、釋出、修正分支
而且還提供了變種版本,master+develop 雙主幹分支的模式。
總結:國外版本的OneFlow發表在2017年,我覺得他確定了基於一個,最多兩個的固定分支進行開發這種原則。提供了企業版本管理過程中的最佳實踐原則,(我覺得)也啟發了AoneFlow這種優秀的Flow。
ExeFlow
ExeFlow是我們公司目前在使用的程式碼管理流程的名稱,主要是吸取了AoneFlow的思想,同時根據我們自己的環境進行一些流程和分支的固化。
要理解這個Flow流程,首先基於我們的實際工作場景:
我們的系統由於主要是面向大型企業內部使用,存在複雜的分發流程和許可權控制,經過長時間的累積業務模型也很複雜各種關聯和引用,所以有一些大型任務的開發週期可能會比較長,到達2-3個月的週期。
我們的迭代週期正常是1個月。流程大概如下:
- 上月末進行迭代計劃評估與安排,這裡會確認下月迭代目標的Story內容與資料。各自主管進行子任務的拆分評估與排期。
- 開發時間一般是2周,我們基本是會在月中設定研發截止線,所有研發任務要在截止線前完成提測。期間有完成的任務可以隨時提測。【涉及分支:Feature,Local,Develop】
- 完整的系統整合測試時間一般是安排在第三週,測試會進行全面的測試。本週研發的主要任務一方面是處理Bug,一方面可以介入下月迭代大項的需求說明與分析。【涉及分支:Feature,Local,Develop】
- 第四周的前三天,我們會切出預釋出的分支在第四周週一時,會給出明確本次能夠上線的Story List,不在清單內的都不允許合併只預釋出環境(也就是我們實際上執行需求在預釋出之前仍舊有變更,只要測試人員通過了整合測試環境,就可以合併並且釋出),本次發版的具體內容和通知也是當天發出。【涉及分支:Feature,Release】
- 發版一般安排在當月的最後一個週四(為了防止有線上問題,所以不能是週五第二天會沒有人員值守)。【涉及分支:Release,Master】
主要經歷了2個大版本的變化
版本1,基本是參考GitFlow
這個版本的固定獨立分支是三條:Master,Develop,Local。核心在於Release分支還是由Develop建立,對於需求變更的支援性不夠靈活。
版本2,是參考AoneFlow
(上圖就是使用gitgraphjs繪製的)
這個版本的固定獨立分支也還是是三條:Master,Develop,Local。
但是核心差異在於Release分支是由Master建立,並且合併需要上線的Feature分支,而Release分支在我們企業的流程中只會存在2-3天的時間。
總結:其實是比較複雜的流程,而且研發的操作的內容實際更多。我們還要鎖定某些分支,設定許可權管理。但是解決了我們的問題,所以從上到下都能替換到複雜流程帶來的好處。
綜述
如果你完整看完了這篇文章,實際上現在需要的並不是馬上選擇當前企業應該選用哪一種Flow管理模型,而是認真的思考企業實際面臨的問題和痛點。越靈活的流程越複雜,對於研發人員初期的接收難度就越高。我們想真正讓研發團隊理解並接受某個管理模型,最重要的是這個東西解決了企業面臨的問題。才能讓管理層、研發自身體會到好處。
我看了很多版本管理軟體的對比,無論是擡Svn打Git或者反之,我覺得都對也都不對。因為無論管理或者技術,本身沒有對錯優劣,問題是場景。如果一個簡單穩定的後期維護專案,強推複雜的管理流程,效果不會好,因為沒有解決任何問題,只會引入問題。
管理的核心在於解決問題,而不是管理行為本身。
引用自Trunk Based Development Introduction↩
畫圖工具是使用gitgraphjs↩