# 前言 在理解 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
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up