Git的程式碼分支策略實踐
目前主流的git工作流模式有git flow、github flow、gitlab flow這幾種,採用不同的程式碼分支策略,意味著實施不同的程式碼整合與上線流程,這會影響整個研發團隊每日的協作方式,因此研發團隊通常需要認真的選擇適合自己的分支策略。
這篇是上面那篇gitlab flow部落格的中文翻譯,翻的很不錯,英文不好的可以直接看這篇
GitLab Flow的使用程式碼管理策略主要有主幹開發和功能分支開發這兩種,功能分支開發又分為以下幾種主流模型,幾種模型各有所長,下面簡述一下
- git flow:出現時間最早,基於git的workflow的開山鼻祖,可以說給出了一個git flow的最佳實踐,缺點是流程比較複雜,release branch和hotfix branch幾乎沒人使用,另外需要長期維護master和dev兩個分支,在規模不大的場景下維護成本比較高
- github flow:相當精簡,只有master主幹和feature branch這兩種,結構相當清晰,缺點是master預設為當前上線的最新版本,在對於版本管理要求比較複雜的場景下靈活性不足
- gitlab flow:出現的最晚,可以說集合了前兩家的長處,既保證只有一個長期主幹,結構清晰,同時也定義了不同場景下的branch,增強了靈活性。
像谷歌、臉書這樣的網際網路大咖,現在採用的都是主幹開發模式,即只有一個master主幹,所有的程式碼合併都在主幹上完成,優點是結構清晰,特別適合快速的CI/CD流程,但是對於團隊的技術能力要求非常高。目前國內的網際網路公司,一般都採用功能分支(feature branch)的開發模式,在開發人員能力良莠不齊的情況下,相對來說對於程式碼的掌控能力比較好。
對於幾種模式的使用場景,如下表所列:(列表來源:極客時間王瀟俊的持續交付專題)
序號 | 情況 | 適合的分支策略 |
---|---|---|
1 | 開發團隊能力很強,需要快速的CI/CD能力 | 主幹開發 |
2 | 有預定的釋出週期,需要執行嚴格的釋出流程 | Git Flow |
3 | 隨時整合隨時釋出,分支merge後經過評審就可以自動釋出 | Github Flow |
4 | 無法控制準確的釋出時間,但又要求不停整合 | Gitlab Flow(帶生產分支) |
5 | 需要逐個通過各個測試環境驗證 | Gitlab Flow(帶環境分支) |
6 | 需要對外發布和維護不同版本 | Git Flow(帶版本分支) |
其實不管是選擇哪種分支策略,都是基於Feature Driven Development(FDD)原則進行專案管理,既先要有issue(需求)輸入,建立對應的功能分支(feature branch)再進行程式碼開發,完成之後合入主幹,同時刪除該功能分支。
個人認為對於中小型的團隊來說,github flow已經足夠完成需求,並且由於微服務架構的流行,一般工程都已經按照服務進行拆分,每個服務一個repo,需要同時進行復雜版本管理的場景不是很多。而現在一般在內網部署都是採取gitlab,所以下面就來說說怎麼在gitlab裡實施github flow(聽起來有點繞口-__-)
-
repo的maintainer在issue上建立問題(新功能或者bug fix),指定issue的接收人或者由團隊成員自己認領,並建立對應的feature branch,這點gitlab比較強大,可以自動建立issue對應的功能分支,github好像沒有這個功能,需要開發人員手工建立並關聯到issue
git.png
-
負責處理的issue的同事Bob checkout這個特性分支(首次開發的話也可以clone這個倉庫並切換到該功能分支),注意本地的分支名字需要和遠端保持一致,否則push的時候會有問題
I:\msaworkspace\bocsh-service-base>git checkout -b 1-test-issue origin/1-test-issue Switched to a new branch '1-test-issue' Branch '1-test-issue' set up to track remote branch '1-test-issue' from 'origin'.
使用 git branch
檢視,發現已經checkout成功並切換到 1-test-issue
這個分支上了,並且本地的 1-test-issue
和遠端倉庫的 1-test-issue
分支已經建立了追蹤關係
I:\msaworkspace\bocsh-service-base>git branch * 1/test/issue master
- Bob在特性分支上進行工作,並每日push程式碼
I:\msaworkspace\bocsh-service-base>git commit -am "test issue track" [1-test-issue 08972ca] test issue track 1 file changed, 1 insertion(+) I:\msaworkspace\bocsh-service-base>git push Enumerating objects: 17, done. Counting objects: 100% (17/17), done. Delta compression using up to 4 threads Compressing objects: 100% (6/6), done. Writing objects: 100% (9/9), 632 bytes | 316.00 KiB/s, done. Total 9 (delta 3), reused 0 (delta 0) remote: remote: To create a merge request for 1-test-issue, visit: remote:http://22.196.66.28/7310754/bocsh-service-base/merge_requests/new?merge_request%5Bsource_branch%5D=1-test-issue remote: To http://22.196.66.28/7310754/bocsh-service-base.git 498d77f..08972ca1-test-issue -> 1-test-issue
這邊注意Bob直接使用了git commit -am引數
這個相當於
git add . git commit -m
同時因為指定了跟蹤關係,所以可以直接用 git push
命令進行推送,git會自動把當前的活動分支的程式碼push到遠端的對應分支上去(還記得前面說的建立對應跟蹤關係嗎),同時git提示我們可以create a merge request去申請把1-test-issue分支合併入master主幹
同時專案管理人員(一般是這個repo的owner或者maintainer)還可以通過點選issue頁面對應的分支,檢視該分支是否被認領,以及該分支的工作進度(Bob,你有木有每天認真幹活啊)

git2.png

git3.png
-
Bob認為功能完成並本地測試通過,在gitlab頁面上提交一個merge request
git4.png
title這邊填寫本次MR的標題,description這邊填寫主要提交的內容,注意必須要包含Closes #1關鍵字,這樣在merge成功後會自動關係關聯的issue(gitlab真的很方便,github裡面這些都是要自己手寫的)

git5.png
這裡的選項可以指定稽核人,給MR打標籤等等操作,注意有兩個選項
- Remove source branch when merge request is accepted.
這個會在合併成功後自動刪除對應的功能分支 - Squash commits when merge request is accepted.
在合併後自動建立一個commit節點,因為git的合併有兩種模式,快進模式只會直接改變HEAD指標的位置,不會建立commit id,這邊為了流程清晰還是建議建立一個commit id
-
maintainer審查程式碼,確認ok後將合併入master,同時刪除該特性分支,並根據#close這樣的關鍵字自動關閉issue
git6.png
如果專案集成了gitlab ci的話,這邊還能看到持續整合的結果,從上面的頁面看到持續整合pipeline的測試和構建也都通過了,點選change選項卡可以檢視改動的地方,稽核無誤後點擊merge按鈕就可以合併入master了
git7.png
這邊看到已經成功合併入主幹,同時這個特性分支也自動刪除,並且自動關閉了關聯的issue
-
如果是準備上線的版本,那在合併成功後還需要打tag,以便於版本的追蹤,我們這邊設定為1.0版本
git8.png
版本打成功後,在tag頁面可以看到歷史版本記錄以及對應的commit id
git9.png
總結:基於issue的專案管理(FDD),非常便於專案的跟蹤和程式碼稽核、版本歷史檢索等,中小型團隊建議實施github flow工作流模型。