# 前言 在理解 Branch & Merge 的功能及概念後,我們可以延伸下個議題,如何使用 Branch & Merge 才是正確的作業流程? Branch 該建立幾個、何時該建立、何時該合併、該如何區分? 關於這個議題,眾說紛紜,Branch 的使用方式分成很多種。 而 Git 官方也有定義一套工作流程 -『Git Flow』,以明確規範在專案過程中,該如何正確的使用 Branch & Merge。 市面上也存在著其他不同的工作流程,以下三種為主要常見的工作流程 1. Git Flow 2. GitHub Flow 3. GitLab Flow </br> # Git Flow 依據官方文件所定義的分支,會有master/main、develop、feature、release、hotfix等五種分支。 其中,分支的種類可再細分為<b><u>主要分支(長期分支)</u></b>以及<b><u>次要分支(短期分支)</u></b>兩種。  </br> ### 主要分支(長期分支) 常駐於工作流程中的分支 1. master/main 用於<b><u>儲存正式的發佈記錄</u></b>。master/main分支的版本應為穩定,且隨時可進行部署的版本。  2. develop 由master/main分支為基底另開而成,為<b><u>主要開發以及功能整合的分支</u></b>  </br> ### 次要分支(短期分支) 當有需求時才會建立的分支,並且在需求結束時即消滅的分支 1. feature 通常由develop分支為基底另開而成,主要為<b><u>單一功能的開發分支</u></b>,如:feature/login、feature/logout等。並且於功能開發完成時,合併回develop分支。  2. release 當develop所整合的功能數量充足時,或者臨近預定的版本發佈日期時,將由develop分支為基底另開而成,作為<b><u>版本發佈的暫存分支</u></b>,以開始版本發佈的前置作業。 版本發佈的前置作業中,不應再添加新功能,僅進行錯誤修復、文件生成或其他與版本發佈作業相關的項目。 當完成版本發佈的前置作業時,將release分支合併回master/main分支,並以tag標記預計發佈的版次。 同時release分支也應合併回develop分支,以同步主要開發分支。  3. hotfix 主要用於<b><u>緊急修復線上重大問題的分支</u></b>,由master/main分支為基底另開而成。 修復完成時,應合併回master/main以及develop分支,以同步修復分支上錯誤的程式碼,並且master/main分支同樣應以tag標記所發布的版次。 一般Bug的修復不涵蓋於hotfix範圍內,應由develop另開分支進行修復,並跟隨下個版本一同進行發佈作業。  </br> # GitHub Flow GitHub Flow中的分支,分為<u>主要分支(master/main)</u>以及<u>功能分支(feature)</u>。  ### 主要分支(master/main) 版本需為穩定且可隨時進行部署。 ### 功能分支(feature) 當有Bug需修復或功能需開發,會由master/main分支為基底另開新分支,<u>分支命名需為具意義且可辨識的</u>(例: refactor-login),讓其他團隊成員可以從分支名稱就清楚明白,你正在進行的工作項目。 </br> ### Pull Request(PR) 當你將feature分支開發完成需合併回master/main分支時,或是開發卡關需要與其他團隊成員討論時,亦或是有其他想法時,均可開啟Pull Request。 同時可使用@標註想討論的對象或是群體,其他團隊成員可透過Pull Request給予你相關的回饋(Feedback),或是審查你所提出的合併分支(Code Review)。 </br> <b>可持續進行推送(Push)</b> 例如:當你建立合併分支的Pull Request時,A成員發現合併程式碼中的某個方法,不符合團隊的規範,於Pull Request中給予你回饋。 當你將該段程式碼調整完成後,可以再次Push上分支,並重新@A成員或其他對象,請對方協助再次審查你的程式碼,或給予你其他的回饋。 </br> <b>Pull Request的合併請求</b> 當你的Pull Request合併請求被同意時,你所修改的程式碼會自動合併至master/main分支。同時,將保留所有歷史修改記錄以及Pull Request的討論過程,以供日後其他團隊成員檢視歷程。 </br> ### Issue tracking 在使用Pull Request或Commit程式碼時,我們可以手動標註該異動所對應的GitHub issue,方便進行Issue tracking,格式通常為「狀態 + Issues編號」,例如:Fixes #42 或 Closes #42 同時,若使用Closes、Fixes、Resolves等狀態關聯issue編號,在PR被同意後,GitHub將會自動幫我們關閉該Issue。 ``` git commit -m "Fixes #42: Corrected the user authentication bug" ``` </br> # GitLab Flow GitLab Flow結合了Git Flow以及GitHub Flow兩種作業流程,並加以改善現有問題。 ### GitLab Flow 分支的改善 Git Flow 由於其分支結構明確,使用上也相對繁瑣且冗長。在加速開發的時候,release與hotfix分支時常會被忘記合併回develop分支。工程師可能在合併回master/main分支後,就繼續趕工其他項目。 與此相比,GitHub Flow 簡化了大部分的流程,僅使用master/main以及feature兩種分支,當合併分支的Pull Request被同意後,GitHub會自動執行合併分支,並準備將相關程式碼部署到正式環境。 然而,在某些時候,開發團隊可能會被要求,不能直接部署到正式環境。 例如: 當系統較不穩定時,需要再進行更完整的測試驗證,或是需要避開系統的尖峰使用時間,於離峰時間再進行部署等等。 因此,在 GitLab 所提出的 GitLab Flow 中,引入了「預生產分支(Pre-Prodution Branch)」和「暫存分支(Staging Branch)」的概念,供開發團隊可以有個暫存環境進行其他測試驗證或操作。 GitLab Flow 保留了 GitHub Flow 快速迭代且不會過於複雜的特性,同時新增的 Pre-Prodution Branch 以及 Staging Branch,讓整體作業流程可以更靈活地應對不同的情境,以提升團隊的開發效率與程式碼的品質。 </br> ### 上游優先(Upstream First) GitLab Flow 核心概念所遵循的原則,旨當需要異動或修復程式時,需要<u>優先從上游分支開始進行處理</u>。 例如:當我們發現正式環境中,存在某個Bug需進行修復時,我們需要從最上游的master/main另開分支進行修復,在修復完畢後將其合併回master/main分支,再依序往下進行部署(master/main -> staging -> pre-prodution -> prodution)。  除非緊急或必要之時,才會由prodution開始操作。否則皆應由master/main開始進行作業。 </br> ### 合併請求(Merge Request,MR) 在GitHub Flow中,如果已經開發或修復完成時,會建立Pull Request(PR)向指定的對象發起合併分支的請求。 而GitLab認為最終仍是執行合併分支的動作,因此在GitLab Flow中,將其稱之為『合併請求(Merge Request,MR)』,本質上與GitHub Flow的PR相同。 </br> ### 合併分支(Merge Branch) GitLab Flow中的合併分支,通常會以`git merge --no-ff`(Non-Fast-Forward Merge)或`git merge --squash`的方式進行分支合併。 除非自行啟用設定,否則GitLab預設不會以Fast-Forward的方式合併分支。 </br> #### Non-Fast-Forward Merge ``` git merge --no-ff ``` 在合併分支時會自動生成一個Commit記錄。 若以主要分支(master/main)的版本記錄來看,每個commit記錄都會對應一個需求或Bug修復,方便日後的分支操作,或是追蹤異動記錄。 同時若在過程中有任何操作錯誤,因為使用Non-Fast-Forward Merge,將會保留開發過程中所有提交的`<commit-hash>`,以及合併分支時所自動生成的`<commit-hash>`,可以很容易的做到復原操作,並且也能讓所有團隊成員清楚看到該需求的所有歷史記錄。 </br> #### Squash Merge ``` git merge --squash ``` 可以將多個Commit記錄壓縮成一個Commit記錄進行合併分支,以簡潔主要分支(master/main)的版本記錄。 </br> # 總結 本篇簡單整理了常見的 Git Flow、GitHub Flow 以及 GitLab Flow。 官方所定義的每種 Work Flow 皆有各自的優缺點 Git Flow 優點:分支結構清晰明確 缺點:執行過程相對繁瑣且冗長 GitHub Flow 優點:分支結構簡單,適合快速開發/迭代的項目 缺點:過於簡單的結構難以應對所有情境 GitLab Flow 優點:彈性的分支結構,可以更容易因應複雜的多樣化情境 缺點:因應彈性的分支結構,需要更完善的CI/CD機制,加速整體效率;同時其複雜性不適合中、小型或快速開發/迭代的項目 </br> 以下為整理後的個人觀點 實務上比較沒有辦法用任何一套標準化的 Work Flow,就套用至所有專案或是所有開發團隊。 當所有官方定義的 Work Flow 均無法滿足團隊需求時,便會從上述的其中一種 Work Flow 作為基底,再依據開發團隊習慣或是專案需求進行客製化調整。如:新增短期的refactor分支,或是將develop與master/main分支整合等等。 團隊成員的開發習慣、專案的需求或是專案的時程等種種因素,皆可能影響 Work Flow 的進行。Work Flow 也就勢必需要進行客製化調整,否則反而會拖累團隊的開發效率,以及專案的時程。 不需強求所有的作業流程都必須遵照 Git Flow、GitHub Flow 或是 GitLab Flow,可以讓所有團隊成員都使用的順手,並且能如期、如質的完成專案需求,就可將其歸類為「合適的Work Flow」。 其規範與定義,只需要在專案啟動時,與團隊成員彼此間達成共識即可。甚至是在專案執行過程中,也可依據專案的狀況或需求等,進行滾動式的調整。 </br> # Git系列文章 [Git 概念、常用指令](https://hackmd.io/@Lion-Le/SyY608E3C) [Git Branch & Merge](https://hackmd.io/@Lion-Le/rJOHUpXTR) [Git Merge & Rebase](https://hackmd.io/@Lion-Le/BJCUrBnTC) </br> # 參考資料 ### 官方文件 [Git Flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) [GitHub Flow](https://docs.github.com/en/get-started/using-github/github-flow) [GibLab Flow](https://docs.gitlab.co.jp/ee/topics/gitlab_flow.html) </br> ### 前輩們的技術文章 [Engine Bai - 團隊協作 Git Flow](https://enginebai.medium.com/git-flow-60b9466e9942) [MrGG(CHANG, TZU-YEN - 張子晏)- 讓我們來了解 GitHub Flow 吧!](https://medium.com/@trylovetom/%E8%AE%93%E6%88%91%E5%80%91%E4%BE%86%E4%BA%86%E8%A7%A3-github-flow-%E5%90%A7-4144caf1f1bf) [沈一二 - 三種版控流程](https://medium.com/@lf2lf2111/%E4%B8%89%E7%A8%AE%E7%89%88%E6%8E%A7%E6%B5%81%E7%A8%8B-29c82f5d4469) </br> >[!Tip] 文章內容皆為個人整理的觀點,以及整理後的個人想法,如內容有錯誤或疑慮的部分,歡迎提出討論,收到後會盡快修正!
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.