短期功能分支

這種分支模型得益於 Git 和 Mercurial 在 2000 年代中期帶來的非常輕量級的分支功能,儘管有證據表明 Google 實際上在數年前就已經在他們的單一版本庫中採用了相同的做法。

無論是直接從主幹建立分支出來,還是在整個程式碼版本庫的分叉中,這些分支最終都會以「拉取請求」的方式回到主幹中。

隨著拉取請求(和程式碼審查)的進步,從「直接提交到主幹」轉移到短期功能分支的團隊規模的上限值降低了。在 Git 輕量級分支之前,這個切換點可以高達 100 人,但現在最多可以是 15 人。對於 16 人或更多的團隊,採用短期功能分支以及相應的持續整合常駐程式提前驗證這些分支,在效率上更為高效,並且當提交進入主幹時也更為可靠。

有一個關鍵規則是分支在合併和刪除之前,它存在的時間長度。簡單來說,分支應該只存在幾天。如果超過兩天,就存在變成長期功能分支(與基於主幹的開發相反)的風險。

–>

另一個關鍵規則是允許多少開發者聚集在一個短期功能分支上。另一個簡單的答案是:開發者數量應該保持在一個(或者如果進行配對開發,則為兩個)。這些短期功能分支不用於團隊內的一般開發活動。它們可以用於程式碼審查,但這完全不同於編寫生產程式碼和測試。

有時社群稱這些分支為「任務」或「主題」分支,而不是長期功能分支。

合併方向性

短期功能分支是真正的分支,合併是第一類概念。在完成短期功能分支上的工作之前,你需要將其與主幹同步。無論你如何執行這個操作,這都是一個有效的合併。觀察此時的分支,它可能看起來比之前的還要新。現在,這些變更必須透過另一個合併操作返回到主幹。在 GitHub 中,對於「拉取請求」(或其他平台中的等效操作),使用者介面可能會為你處理最後的合併操作,甚至可能會刪除短期功能分支。

簡而言之:允許合併到短期功能分支,以使其接近主幹的 HEAD。只有在結束短期功能分支(並在刪除之前)時,才允許將合併提交到主幹。

兩個開發者同時進行短期功能分支的開發

假設同時進行兩個功能的開發:功能 X 和功能 Y。兩者都需要一天的時間完成,並且有兩個開發者獨立地進行工作。如果是該團隊的慣例是配對開發,則會有四個開發者。在將短期功能分支合併回主幹或主要分支之前,通常需要先從主幹或主要分支合併到變更,然後才是將變更合併回主幹或主要分支。

工作流程包括:

  • 嘗試合併到主幹或主要分支。如果被阻止,則在再次嘗試推送之前,從主幹或主要分支進行合併或拉取。
  • 在嘗試將任何變更推送到主幹或主要分支之前,從主幹或主要分支進行推測性合併或拉取。

如果從其他分支中沒有要合併的內容,那麼後者將不會留下任何痕跡。

包括工作的機器

實際上,開發者在自己的個人電腦上進行工作。這既包括他們的「工作目錄」,也包括帶有分支的本地 Git 複本。

白點表示一般開發工作(從整合開發環境保存文件),綠點則表示通過本地建置驗證並可能進行了本地提交。

每個開發者在工作期間,都會維護本地 clone 上的主幹或主要分支,以及他們自己的短期功能分支。事實上,在一段時間內,他們的短期功能分支可能尚未存在於共享的程式碼版本庫中。

個人偏好

在某個時候,短期功能分支必須通過合併操作與主幹同步,然後將結果合併回主幹(並刪除該分支)。有多種方法可以實現這一點,有些團隊有相應的策略,而有些團隊則則將其交由開發者的個人喜好來決定。

暫存提交 (Git stash)

有些人在執行 git pull 之前會先執行 git stash,然後再執行 git stash pop 。這樣做的原因是,當你執行 pop 時,你的工作目錄可能處於合併衝突的情況,而這需要你在下一步之前解決它。這種方法會導致你的更改成為一個單獨的提交,並位於分支的 HEAD(就像 Subversion 做的那樣)。

重定提交基底

有些人使用 git rebase。可以參考 Atlassian 的文章 Merging vs. Rebasing 和 ThoughtBot 的文章 Git Interactive Rebase, Squash, Amend, Rewriting History ,這兩篇文章都討論了 squash 的相關內容。

即便使用這種模型,你仍然會遇到合併衝突。在推送結果之前,必須在本地解決衝突,或者執行進一步合併(希望是到 main 分支)。

問題和陷阱

當專注在拉取請求時,可能會忽略將多個相較小變更直接提交進主幹的好處,而這個好處是能讓所有人感受到的。從 90 年代末開始,高產量的 XP 團隊每天(每對開發者)會將數十個提交進入主幹。如果團隊改變計劃的話,每個提交都是一個遞增的前進步驟,並且能夠按原樣上線。這種工作方式的一個錯誤思維是,每個敏捷故事或卡片只對應一個拉取請求(僅此而已)。要擺脫這種思維陷阱,可以練習(例如)為重構進行一個拉取請求,並將其整合或合併到主幹中,接著再為一個新功能進行一個拉取請求(並將其整合到主幹中),然後再進行另一個重構(再次整合到主幹中)。對於這三個拉取請求,它們共享相同的故事或卡片關聯,但可能有不同的短期分支名稱——每個分支在合併或整合後都會被刪除。

違反約束

如果你將部分完成的短期功能分支合併到其他地方,那麼你已經違反了主幹開發的約束。對於短期功能分支,不允許這些操作:

  1. 執行到一半時,合併到主幹(或主要分支),至少在提交無法獨立投入正式環境時是不允許的。
  2. (無論任何方式)合併到其他人的短暫功能分支是不允許的。
  3. (無論任何方式)合併到任何發布分支(如果有的話)是不允許的。
  4. 直接從或往開發者個人電腦上的複本進行合併是不允許的。
  5. 除非是你的配對開發夥伴,其他開發者加入你的短期功能分支是不允許的。

短期功能分支的替代方案

對於小型團隊來說,還有一個更傳統的替代方案:直接提交到主幹 。許多人仍然喜歡這種工作方式,如果整個團隊都能夠在不損壞建置伺服器的情況下進行,那麼代表團隊做得很好。

還有一種是對提交修改審查的工作方式,這是在 Google 的 Mondrian(2006年)中概述的,隨後使用開源工具 Gerrit 和 Rietveld (2007-2008 年) 為非 Google 團隊提供了這種方式。

這兩種替代方案以及短期功能分支在 風格和折衷 中進行了比較。

其他參考資料

顯示參考資料

26 Apr, 2007, Blog Entry
Introducing Branch By Abstraction