在 Git 開分支很便宜,真正痛苦的是合併,過與不及都是災難,因此如何依專案性質、團隊習性及管理要求訂出合宜的分支策略是個重要問題。別人耍得虎虎生風的大關刀,到你手上不是敲到頭就是閃到腰,故分支策略很難拿別人的現成做法硬套蠻幹,需與專案、團隊與制度契合才能順暢。 橫柴入灶其實也行,隨便挑一個分支策略規定所有人照做就是了,但如此肯定產生大量浪費(為了符合規定做一堆重複或沒效益的事),不符精實開發精神。因此,新手的我遇到一個挑戰:如何挑選並調校出適合專案性質團隊偏好又能符合公司制度的 Git 分支策略?

既然是張白紙,就從參考別人的成功經驗開始吧。

研讀了一些網路文章,並附上我的心得整理:

4 branching workflows for Git

作者整理了四種常見的 Git 分支策略:

  1. Git Flow
    Git 界最有名的工作流程。master、develop 兩個長期分支並行,開發期間會用到以下分支:

    • feature-* 從 develop 產生分支,修改完成後併回 develop
    • hotfix-* 緊急修改線上版本錯誤時使用,由 master 產生分支,改完合併回 master 及 develop
    • release-* 上線用分支,由 develop 分出來,合併回 develop 及 master

    Git Flow 的優點是分支狀態系統化、清晰、相關工具豐富,缺點是歷程複雜且不利於 CD/CI(Continous Delivery/Continous Integration)

  2. GitHub Flow
    master 分支永遠為可部署使用狀態,修改時先切出分支,改完發出 PR(Pull Request) 經負責人同意才併入 master,併入後應立即部署。
    GitHub 流程的優點是比 Git Flow 簡單,適合 CD/CI,缺點是 master 容易變得不穩定,缺少發行、部署方面的管理機制。

  3. GitLab Flow
    比 GitHub 流程多了 staging、production 等分支,有以下原則:

    • 使用 feature 分支,需經 Code Review 才可 Commit 進 master
    • 要求所有 commit 都要測試(不只 master)
    • 自動部署(基於分支或 Tag)
    • Tag 靠人工加註而非 CI
    • 已 Push 的 Commit 不得 Rebase
    • 每個人都從 master 開始
    • 修 Bug 順序先 master 再 release
    • Commit 訊息要明確說明用意

    GitLab Flow 的優點是專注於 CI/CD,Git 歷史軌跡清晰,缺點是比 GitHub Flow 複雜。

  4. One Flow
    Adam Ruka 主張 Git Flow 過於複雜而提出改良版 - One Flow。核心精神與 Git Flow 相似,但移除了 develop 分支,只留 master。
    One Flow 的優點是歷程軌跡較清楚好讀,可依團隊決策彈性調整;缺點為不適合 CD/CI。

OneFlow - a Git branching model and workflow

OneFlow 的作者 Adam Ruka 對 OneFlow 應用所做的完整說明。並透過實例說明如何建立 feature 分支再合併回 master、建立 release 分支,加 Tag 再併回 master、從 release 分支 Tag 建立 hotfix 分支再併回 master。

Git 分⽀開發流程和策略 by ihower

資深 Git 老鳥的實戰心得分享:

  1. 三種遠端 Repo 管理方式:所有開發者都可以 Push、開發者發 PR 給整合管理員放上正式 Repo (似 GitHub Fork+PR 機制)、階層式(分司令官跟副官,超大型 Open Source 如 Linux Kernel 的玩法)
  2. 介紹 Git Flow,優缺點前面已講過
  3. Ruby on Rails 採 GitHub Flow 再加了 maintenance 分支(維護舊版,如 2-3-stable、4-0-stable...),Tag 打在 master 上, 透過 preview、beta 方式釋出,有很多 Open Source 專案採類似做法
  4. CMake Git 流程:master 分出 feature,做好先併進 next (或稱 staging)分支,在 next 測試 OK 後,feature 分支併入 master。 master 可併入 next 減少合併衝突,但 next 不可併入 master。每天凌晨 1:00 自動測試 next 分支。
  5. 講個祕訣 若 feature 分支要開發很久,記得定期合併或 Rebase master/develop,以免時間太久了合併不回去
  6. 合併前先做 Rebase 讓歷程更清晰好讀! 花點功能 Rebase 再 Merge,線圖會很好看,但這很吃功力。(投影片 p.31-37)
  7. 實務上 feature 的合併有可能變成惡夢,端賴團隊紀律、程式架構模組化、不因時程壓力輕率合併防止失控
  8. 講個祕訣 feature 分支放久可能會臭掉併不回去,若無法馬上上線也可合併但先把功能關閉或把 UI 藏起來,或設權限對少數對象開放
  9. 發佈間隔較長時,需要穩定的 release 分支

Adopt a Git branching strategy

微軟的分支策略建議:

  1. 開 feature 分支加功能及改 Bug、透過 PR 將 feature 分支併入 master、保持 master 的品質與即時性
  2. feature 分支命名範例:
    • user/username/description
    • user/username/workitem
    • bugfix/description
    • features/feature-name
    • features/feature-area/feature-name
    • hotfix/description
  3. feature 分支放太久不合併會臭掉,加上功能控制旗標讓未完成的 feature 分支也能合併進來。
  4. 合併前應做 Code Review,PR 是一種強制審查手段。建議:兩個 Reviewer、若已有 Code Review 機制,把 PR 審查納進去、Reviewer 工作適度分攤品質會較好、附上編譯結果或測試環境連結方便驗證。
  5. 維護 master 品質與即時性的方法
    • 加入的程式碼需通過測試且為最新版
    • 靠 PR 把關
    • PR 建立時自動加入 Reviewer
    • 能成功編譯的程式才可完成 PR
  6. 利用 release 分支協助及管理上線版本的調整。release 可長期存在但不可併回 master,每個 release 代表一個你必須繼續支援的版本, 若不再支援可將其上鎖不再接受變更
  7. release 分支的修改(hotfix)如何融回 master?
    從 master 開新的 feature 或 bugfix 分支,以 Cherry-Pick 方式拉回 release 分支上特定的 Commit 到新分支,將新分支合併回 master。
  8. release 分支不建議用 Tag:需人工管理維護,容易遺忘搞混
  9. 必要時可針對特別部署版本建立專屬分支並比照 release 分支管理,如:deploy/performance-test。用第 7 點的做法將對其所做調整拉回 master。

註:文章下方的影片有 TFS 針對 Git 分支管理提供的一些貼心功能。

【同場加映】如果你還在用 TFVC,這裡有微軟官方版 TFVC 分支策略指南:Learn about branching strategies for Team Foundation Version Control (TFVC) and how to select an effective strategy

Survey of available branching strategies of Git on Visual Studio.


Comments

Be the first to post a comment

Post a comment