嗨,世界
Published in

嗨,世界

其他分支模式

除了整合與發佈之外,還有一些特殊的分支模式就在這裡一並探究。

實驗性分支 Experimental Branch

如同字面所說,實驗性指得是這個分支一開始的目的就不是要上線,而是『實驗』,通常是驗證某些概念、技術的可行性,以幫助接下來的決策。實驗性分支可以在任何地方展開,主線、功能分支都有可能,也可以同時開幾個不同實驗分支來測試不同的技術並且做比對用以選出最適合的。

既然是實驗,就可能有一些失敗、被丟棄的分支。就算是成功的實驗分支也不一定適合直接整合。因為實驗的重點是一個概念的可行性,因此通常對於品質比較不在意,如果真的要把實驗成功的分支整合至主線(或其他分支比如功能分支),那麼品質這塊就需要再做一點修正。也可以直接棄用實驗分支或是拿實驗分支作為參考,直接在適合的地方重寫符合品質規範的程式碼 (production code)。如果選擇棄用,可以考慮先加個 exp/* 的 tag,再行刪除分支,這樣未來需要參照時會比較容易找到。

分支建立的時機有兩種:一種是一開始就知道實驗的標的,另一種是功能開發到一半才發現正在做的事情其實是某種實驗,此時就需要把實驗分支建立出來,同時開發的分支需要重設至應有的位置,以便繼續開發非實驗性的部分。

激進分支 Future Branch

(Future Branch 翻成未來分支有點不知所云,先亂翻成激進好了….因為通常都是要翻掉架構才需要用的)

在持續整合情境下,我們希望所有的變更都可以持續的整合到主線。但偶爾就是有些任務是不容易持續整合的(通常是架構性的調整),不好拆小,比較適合整個做完之後再行整合。可以想像成是持續整合時的功能分支,直到整個功能做完後才會進行主線整合。

激進分支與功能分支的最大不同,在於激進分支只能有一個,當然這不是硬性規定,不過限制在一個可以最小化整體開發的複雜度,確保與主線不要差異太多,也沒有其他分支的差異需要煩惱。

因為激進分支本身特性的關係,通常也不適合邊開發邊把主線整合進來,而是把整合延遲到開發完畢時,如同系列文第二篇提到的低頻率整合。這樣會提高整合的成本。前提是採用持續整合所需的成本遠高於激進分支,或根本無法持續整合,我們才應該採用激進分支。多數情況下盡量把事情拆小,或是透過抽象化部分逐步替換,就可以避免使用此模式,也許唯一需要的就是整體的架構性調整。

為了避免造成與主線過大的落差,激進分支仍應該盡可能的整合回主線。

協作分支

分支的目的是與其他成員更為順暢的(就某個特定範圍)協作

其實不管是功能分支、實驗性分支、激進分支都可以與其他人協作,當然如果需要協作則要把分支建立在 shared repo 上,讓所有人都看得到變更狀況。理想狀態下除了主線的外的協作分支越短越好,避免與主線過大落差。

整合頻率越低時,協作分支的需求會越高,因為彼此無法及時看到其他人的變更。持續整合的狀態下大家的變更最晚一天就會出現在主線上,可說幾乎不需要協作分支(唯一例外是實驗性分支)。

團隊整合分支 Team Integration Branch

子團隊先行內部整合,再整合至主線

當團隊有時需要拆分成不同的子團隊(通常是人數變多),這時如果不同子團隊的技能水準、流程、節奏無法互相搭配時,要進行大規模的持續整合會變得比較困難。此情境下子團隊各自確保可以達到主線的規範(比如健康度)後,再行主線整合。

由於各子團隊可以先行內部整合,好處就是可以比較彈性的開發(如同功能分支與持續整合的對比),也許有的團隊內部走持續整合,有的走長達數個月的功能分支,在此模式下都可以和平共處。團隊整合分支其實就是協作分支的正式版本 — 依照組織架構所建立的協作分支。

常見分支流程

接下來提升一個層次,來看看三個常見的分支流程。因為前面我們已經探究過各種模式,此時就可以就各流程使用的分支模式,來思考其適合的情境以及優缺點:

Git-flow

https://nvie.com/posts/a-successful-git-branching-model/

使用主線 (origin/develop) 加上功能分支,而 origin/master 則是作為完備度分支中的 production 分支。加上發佈分支模式,每次發佈都需要建立分支,透過發佈分支模式把主線上的東西搬移至 origin/master 。緊急修復則是透過修補分支來處理。

身為早期的 GIT 主流開發流程,git-flow 對於功能分支的長度、整合頻率、健康度等沒有太多規範。(當時可能也沒這麼注重這些)

在 2010 年,軟體有多個客製化版本是很正常很主流的事情,git-flow 使用發佈分支也就很能適應這樣的情境,但當開發轉為 web 應用程式時通常只有一個版本,使用 git-flow 就會造成多餘複雜度。

GitHub Flow

http://scottchacon.com/2011/08/31/github-flow.html

其實現在 github / gitlab / bitbucket 之類的工具盛行,許多認為自己跑 git-flow 的人實際上是在使用 github-flow。GitHub Flow 核心有基於單一版本、提高整合頻率、可隨時發佈的主線幾個特性。

主線叫做 master,使用功能分支,透過 Pull Request 機制做主線整合,同時實現 Reviewed Commit。所以變更都是 Pull Request,只要品質合格就可以整合回主線,主線維持可發佈狀態,因此沒有使用發佈分支、修補分支的需求。

與 Git-flow 相同的是都有主線以及功能分支。

Trunk-Based Development / Continuous Integration

https://trunkbaseddevelopment.com/

所有工作都在主線(或主幹 Trunk)上進行,減少分支(比如功能分支)所造成的不一致,理想狀態是每天持續整合至主線,如果團隊成員較為複雜或較為龐大,則會使用短期的功能分支來處理。團隊依照需求可能會用發佈分支來處理發佈,也可以直接從主線發佈。

總結

程式的開發隨著成員增加與步調的提升,變得越來越為複雜。分支是強大的,讓我們可以把複雜度切分處理,但分開處理完還需要整合才會是一個完整的產品。所以,對於分支策略的第一個準則:思考最後要如何整合。整系列文介紹各種分支與整合模式的目的就是要讓我們了解有哪些選項、各自的成本與效益,讓我們有比較多決策的依據。

第二準則:沒有必要不要創造分支。有分支就需要整合,因此隨時思考這件事情有沒有辦法透過其他更好的方式來避免建立新分支:下 tag 可以嗎?透過模組化呢?流程上的改善?建立新分支雖然很低成本,但出來跑還是要還,該處理的複雜度如果不及時處理,最後(整合主線時)還是會遇到。

第一篇提到分支有差異度逐漸增加的趨勢,越久沒整合差異就越大。因此第三準則是:盡可能提高整合頻率,這代表了很多大工程,從流程調整、技能提升、心態改變等。

想要提高整合頻率,就必須要降低整合的困難度。第四準則:注意那些造成整合困難的事物。這有可能是流程問題,也有可能是系統架構不夠模組化,認知到不足的地方是改變的第一步。

最後,各種模式或流程沒有好或壞,只有適不適合當下的情境。當我們能夠對這些模式或流程有更深入的認識時,才有辦法選出更適合情境的組合。而持續的去認知到我們有哪些選擇,也有助於未來開發流程的更加精進。

--

--

追蹤我們的粉絲團以獲得最新發文通知 https://www.facebook.com/thingsaboutwebdev/

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store