天天看點

一切的源頭,代碼分支政策的選擇

記得大概是一年前吧,我與好友老吳喝茶聊天時,讨論到:高效的持續傳遞體系,必定需要一個合适的代碼分支政策。

我告訴老吳:“采用不同的代碼分支政策,意味着實施不同的代碼內建與上線流程,這會影響整個研發團隊每日的協作方式,是以研發團隊通常會很認真地選擇自己的政策。"

老吳是一名有多年開發經驗的資深架構師,當時正好要接手一個架構團隊,從個人貢獻者向團隊管理者轉型。他個人對代碼管理工具可謂熟之又熟,甚至連“老古董”的CVS都可以跟你聊半天。但他在為團隊制定代碼分支管理政策時,還是慎之又慎,足見其重要性。

最後我們發現,要确定選用哪種代碼分支管理政策,需要先假設幾個問題,這幾個問題有了答案,也就代表你找到了适合的方向。你需要思考的幾個問題如下:

1.Google和Facebook這兩個網際網路大咖都在用主幹開發(Trunk Based Development簡稱TBD),我們是不是也參照它倆,采用主幹開發分支政策?

2.用Google搜尋一下,會發現有個排名很靠前的分支政策,叫“Asuccessful Git branching model”(簡稱GitFlow),它真的好用嗎?團隊可以直接套用嗎?

3.GitHub和GitLab這兩個當下最流行的代碼管理平台,各自推出了GitHubFlow和GitLabFlow,它們有什麼差別?适合我使用嗎?

4.像阿裡、攜程和美團點評這樣國内知名的網際網路公司,都在用什麼樣的分支政策?

今天,我想再沿着當時的思考路徑,和你一起回顧和總結一下,希望能夠帶你全面了解代碼分支政策,幫助你做出合适的選擇。

談談主幹開發(TBD)

主幹開發是一個源代碼控制的分支模型,開發者在一個稱為“trunk”的分支(Git稱 master)中對代碼進行協作,除了釋出分支外沒有其他開發分支,Google和Facebook都是采用“主幹開發”的方式,代碼一般直接送出到主幹的頭部,這樣可以保證所有使用者看到的都是同一份代碼的最新版本。“主幹開發”确實避免了合并分支時的麻煩,是以像Google這樣的公司一般就不采用分支開發,分支隻用來釋出。

大多數時候,釋出分支是主幹某個時點的快照。以後的改Bug和功能增強,都是送出到主幹,必要時cherry-pick(選擇部分變更集合并到其他分支)到釋出分支。與主幹長期并行的特性分支極為少見。

由幹不采用“特性分支開發”,所有送出的代碼都被內建到了主幹,為了保證主幹上線後的有效性,一般會使用特性切換(featuretoggle)。特性切換就像一個開關可以在運作期間隐藏、啟用或禁用特定功能,項目團隊可以借助這種方式加速開發過程。

特性切換在大型項目持續傳遞中變得越來越重要,因為它有助于将部署從釋出中解耦出來。但據吉姆·伯德(JimBird)介紹,特性切換會導緻代碼更脆弱,更難測試,更難了解和維護,更難提供技術支援,而且更不安全。

他的主要論據是,将未經測試的代碼引入生産環境是一個糟糕的主意,它們引發的問題可能會在無意間暴露出來。另外,越來越多的特性切換會使得邏輯越來越混亂。

特性切換需要健壯的工程過程,可靠的技術設計和成熟的特性切換生命周期管理,如果不具備這三個關鍵的條件,使用特性切換反而會降低生産力。

根據上面的分析,主幹開發的分支政策雖然有利幹開展持續傳遞,但是它對開發團隊的能力要求也更高。

主幹開發的優缺點

優點

1.頻繁內建,每次內建沖突少,內建效率高。

2.能享受持續傳遞帶來所有的好處。       

3.無需在分支之間做切換。

缺點

1.太多的團隊成員同時工作在主幹上,到釋出的時候就可能出現“一粒老鼠屎壞了一鍋粥”這樣的災難。     

2.要借助特性切換等機制來保證線上運作的正确性,這會引 入新的問題。    

談談特性分支開發

和主幹開發相對的是“特性分支開發”。在這個大類裡面,我會給你分析GitFlow、GitHub Flow和GitLabFlow這三個常用的模型。

第一,GitFlow

我們在Google上查關鍵詞“branchmodel”(也就是“分支模型”),有一篇排名比較靠前的文章“A successful Git branchingmodel”,它介紹了 GitFlow模型。

Git剛出來的那些年,可參考的模型不多,是以GitFlow模型在2011年左右被大家當作了推薦的分支模型,至今也還有項目團隊在使用。然而,GitFlow煩瑣的流程也被許多研發團隊吐槽,大家普遍認為hotfix和release分支顯得多餘,平時都不會去用。

一切的源頭,代碼分支政策的選擇

第二,GitHubFlow

GitHubFlow是GitHub所使用的一種簡單流程。該流程隻使用master和特性分支,并借助 GitHub的pull request功能。

一切的源頭,代碼分支政策的選擇

在GitHub Flow中,master分支中包含穩定的代碼,它已經或即将被部署到生産環境。任何開發人員都不允許把夫測試或未審查的代碼直接送出到master分支。對代碼的任何修改包括Bug修複、熱修複、新功能開發等都在單獨的分支中進行。不管是一行代碼的小改動,還是需要幾個星期開發的新功能,都采用同樣的方式來管理。

當需要修改時,從master分支建立一個新的分支,所有相關的代碼修改都在新分支中進行。開發人員可以自由地送出代碼和送出到遠端倉庫。

當新分支中的代碼全部完成之後,通過GitHub送出一個新的pullrequest。團隊中的其他人員會對代碼進行審查,提出相關的修改意見。由持續內建伺服器(如Jenkins)對新分支進行自動化測試。當代碼通過自動化測試和代碼審查之後,該分支的代碼被合并到master分支。再從master分支部署到生産環境。

GitHubFlow的好處在于非常簡單實用,開發人員需要注意的事項非常少,很容易形成習慣。

當需要修改時,隻要從master分支建立新分支,完成之後通過pullrequest和相關的代碼審查,合并回master分支就可以了。

第三,GitLabFlow

上面提到的GitHubFlow,适用于特性分支合入master後就能馬上部署到線上的這類項目,但并不是所有團隊都使用GitHub或使用pullrequest功能,而是使用開源平台GitLab,特别是對于公司級别而言,代碼作為資産,不會随意維護在較公開的GitHub上(除非采用企業版)。

GitLabFlow針對不同的釋出場景,在GitHubFlow(特性分支加master分支)的基礎上做了改良,額外衍生出了三個子類模型。

分支模型            說明    

帶生産分支       1.無法控制準确的釋出時間,但又要求不停內建的。    

                         2.需要建立一個production分支來放置釋出的代碼。    

一切的源頭,代碼分支政策的選擇

帶環境分支       1.要求所有代碼都在逐個環境中測試通過。    

                         2.需要為不同的環境建立不同的分支。  

一切的源頭,代碼分支政策的選擇

帶釋出分支         1.用于對外界釋出軟體的項目,同時需要維護多個釋出版本。

                           2.盡可能晚地從master拉取釋出分支。    

                           3.Bug的修改應先合并到master,然後cherrypick到release 分支。

一切的源頭,代碼分支政策的選擇

GitLab Flow的特性分支合入master用的是“MergeRequest”,功能與GitHubFlow的“pullrequest”相同,這裡不再贅述。

通過Git Flow、GitHubFlow和GitLabFlow(3個衍生類别)這幾個具體模型的介紹,我給你總結一下特性分支開發的優缺點。

優點

1.不同功能可以在獨立的分支上做開發,消除了功能穩定前彼此幹擾的問題。  

2.容易保證主幹分支的品質:隻要不把沒開發好的特性分支合入主幹分支,那麼主幹分支就不會帶上有問題的功能。    

缺點    

1.如果不及時做merge,那麼把特性分支合到主幹分支會比較麻煩。

2.如果要做CI/CD,需要對不同分支配備不同的建構環境。 

選出最适合的分支政策

上面我跟你講到的分支模型,都是IT研發領域比較流行的。雖然有些政策帶上了代碼平台的辨別,如GitHubFlow,但并不意味着該政策僅限幹GitHub代碼平台使用,你完全可以在自己搭建的代碼平台上使用這些政策。

接下來,我就總體歸納一下什麼情況下應該選擇什麼樣的分支政策。

一切的源頭,代碼分支政策的選擇

國内網際網路公司的選擇

GitLab作為最優秀的開源代碼平台,被多數網際網路大公司(包括阿裡,攜程和美團點評等)所使用,這些大廠也都采用特性分支開發政策。當然,這些大公司在長期持續傳遞實踐中,會結合各自公司的情況做個性化的定制。

比如,攜程公司在GitHubFlow的基礎上,通過自行研發的內建加速器(LightMerge)和持續傳遞Paas平台,一起完成內建和釋出。

再比如,阿裡的AoneFlow,采用的是主幹分支、特性分支和釋出分支三種分支類型,再加上自行研發的Aone協同平台,實作持續傳遞。

總結

今天,我主要給你介紹了各種代碼分支政策的特性。

你應該已經比較清晰地了解了“主幹開發”和“特性分支開發”兩種政策的各自特性:

1.“主幹開發”內建效率高,沖突少,但對團隊個人的開發能力有較高要求;