團隊協作 Git Flow

Engine Bai
8 min readMar 25, 2022

今天來講一個對於開發也非常重要的一環:團隊協作 Git Flow,這邊講的比較像是概括性的流程,外面非常多不同的專屬流程、客製化或變形,只有合適的流程、沒有所謂最好的流程,不用太拘泥說哪種流程最好。

這篇會講三大面向:

  1. Why? 了解為何需要這流程,從宏觀角度看這流程的重要性。
  2. What? 在這流程當中我們會有哪些分支。
  3. How? 我們的工作流程會是長怎麼樣。

這邊不會講解 Git 如何使用,而且看這篇文章需要對 Git 有基本的熟悉程度,如果對分支、合併等都不熟,請先學習如何使用 Git。

第一、為何需要這流程?

  1. 不同的開發環境:我們可以透過 Git Flow 來針對不同的開發環境建置不同的測試或正式版本。
  2. 協作、協作還是協作:有了 Git Flow 我們會有良好的共同程式開發和版控協作流程,不同開發者可以同時開發不同功能,或者同時一起開發一個大功能。另外也可以開發和發佈同時進行互不受影響。
  3. 統一受規範的流程:有了 Git Flow 我們會有一個統一、受規範、自動化(搭配 CI/CD)的出版流程,自動化發佈版本流程在開發流程中佔有重要的角色,不需人為介入可以減少人為犯錯的風險、同時提升效率。

第二、What 我們有哪些分支?

概觀來說,我們的 Git 分支主要有兩種型態:

  1. 主要分支:有 master and release 兩種,這兩個分支都永遠存在。
  2. 支援分支:有 feature, bugfix, refactor 等等,這個過完 PR 合併之後就會刪除,屬於暫時行的分支。

我們來個別來看這些分支:

主要分支

  1. master 其實應該稱作 develop,顧名思義就是正在開發中的主要分支,大部分分支都會從這邊開出去、最後也會合併回這個分支。
  2. release 目前線上穩定版的分支或者即將釋出的 Staging 版本,我們會不斷將 master 合併進入 release 版本。

我們通常都會針對這兩個分支設定一些保護機制(GitHub 和 GitLab 都有支援),像是「分支不能刪除」、「master 合併之前都需要經過 PR (MR)」或者「Foced push 是不被允許的」也就是不能修改過去的提交歷史…等規則。

支援分支

我們依照不同的工作類型來建立我們的支援分支,常見的像是 feature, bugfix, hotfix, refactor。命名規則以我們習慣的命名方式就會是這些工作類型當作開頭,然後用 slash / 分隔,後面加上我們要做的內容,像是 feature/send-gift(如果是多個字的話,我們會用 dash — 分隔)然後這些分支完成且合併之後我們就會刪除,在開發中途你都可以隨意改動、編輯你的 commit,但請小心使用!!

第三、How 我們的工作流程

我們會從最平常的功能開發、到發佈 Staging / Production 版本、處理 Hotfix 的流程一一講解。

單人開發單一功能

這個是最簡單的情境,是用在單人開發而且「一個接著一個」有順序性的開發單一功能。

  1. 就從 master 開出分支開始做功能。
  2. 做完之後對 master 開 PR。
  3. 做完 code review 之後合併回 master,完成!這邊我們合併回 master 都會使用 squash 合併,把多個 commit 壓成一個 commit 紀錄。這麼做的原因在於對於 master 我們關注的是「功能」層面,也就是何時做了什麼功能,而不是功能底層如何實作,不在乎 feature branch 的諸多 commits。

單(多)人開發不同功能

這情境是單人或多人「同時」開發不同功能,基本上流程和上述非常接近

  1. 不同功能就從 master 開出不同分支分頭進行 feature/A, feature/B。
  2. 假設 feature/A 先做完了對 master 開 PR、code review、合併。

3. 這時候 feature/B 應該要先 rebase 一次 master,如果有衝突就先解一解,解完之後 force push 到 feature/B,然後再繼續進行 B 的功能開發。

4. 做完 code review 之後合併回 master,完成!

多人一起開發同一功能

這情境是大家一起同時開發「同一個」功能,這情境會和上述的「單(多)人開發不同功能」類似,只是有一些不同而已。假設以兩個人同時開發收送禮物 同一功能為例:

  1. 兩人在最一開始的時候,先從 master 開出一個 feature branch 叫做 feature/gift 作為基底,而且這個 feature/gift 就是暫時充當原本的 master,後續開發都是對這個 feature/gift 去開分支、去合併。

2. 接著流程就和上述的「單(多)人開發不同功能」一樣,只是基底是 feature/gift。

3. 等整個功能都完成之後,我們在開一個 feature/gift 對 master 的 PR,這邊我們不會進行 code review,因為這些變更在前面開發的時候都已經看過了。

Bugfix 問題修正

這邊不是指 Hotfix 線上問題需要緊急修正的流程,指的是一般可以跟著後續版本一起釋出的 bugfix。我們的流程其實是和前面這幾個流程一樣,只是從 feature 變成 bugfix 而已。

釋出 Staging 版本

當我們已經都完成所有要釋出的功能和問題修復後,我們就可以釋出 Staging 來做最後上線前的完整功能以及回歸 (regression test) 測試。步驟則是:

  1. 將 master 合併到 release,我們會用 –no-ff 參數來強制產生一個 merge commit,好讓我們有一個紀錄。(合併有可能可以 fast-forward,這樣歷史紀錄就看不出有合併,加了 –no-ff 後即使可以 fast-forward 也會產生一個合併 commit)

釋出 Production 版本

當做完完整功能和回歸測試沒問題後,我們準備發佈正式版,發正式版直接在 release 下 git tag 即可完成,不過通常我們用會 GitHub Release 來發佈,這樣可以同時寫下版本資訊。

Hotfix

這是指線上版本有問題需要緊急修復,這流程大家比較不常遇到(常遇到表示程式開發品質堪慮,需要好好檢討!)加上流程比較不直覺,大家比較容易做錯或忘了某個步驟,需要多加注意!!

  1. 因為是線上版本有問題,所以我們會從 release 開出 hotfix/XXX 去修正。

2. 修正完之後會對 release / master 兩邊同時開 PR,對 release 開表示修正完後就可以立刻釋出;而對 master 開的原因主要會是套用同樣的變更在開發中的分支。

3. 對 release 的 PR 如果看完沒問題就可以走上述「釋出 Production 版本」。

4. 最後在合併對 master 開的 PR。

結語

這個流程講述了大致的方向和可行的步驟,這流程通常會搭配 CI/CD 在某些流程會自動觸發執行某個工作,像是: PR 合併到 master 之後就會觸發 CI/CD 編譯建置測試版給測試人員等,而詳細的流程可視各公司不同的開發環境、測試流程、發版流程等調整,基本上大原則會是一樣的。

參考資料:

Git flow 原始發起者?的文章 https://nvie.com/posts/a-successful-git-branching-model/

GitHub 流程 https://docs.github.com/en/get-started/quickstart/github-flow

GitLab 流程 https://docs.gitlab.com/ee/topics/gitlab_flow.html

--

--

Engine Bai

白昌永 (大白) Software Engineer, Athlete, Learner. Focused on Mobile / Backend / AI + ML