淺談 Git Flow 與 commit 規範

前言

Git Flow 與 commit 一直都是許多 Git 新手的痛,畢竟一開始學習是很少會有機會碰到多人協作,因此來寫一篇筆記記錄一下什麼是 Git Flow 以及為什麼要做 commit 規範。

Git Flow

Git Flow 是在 2010 年被推出的一個觀念,注意!是觀念

A successful Git branching model

在原文中我們可以看到這一張圖

Git Flow

首先我在這邊假設你已經懂什麼是 Git Branch (分支),因此上圖中的一條一條都是一個 Branch,而那條一條的並不是我們的重點,而是它上面標註的名稱

  • main master
    • GitHub 已於 2020/10 將 master 改叫 main,因此只要是新的儲存庫的分支都會主要改成 main,可參閱此連結
  • develop
  • feature
  • hotfix
  • release

這五大分支就是 Git Flow 的精髓。

main

main 分支基本上可以區分為兩種狀況

代表分支名稱:main

初始化 main

這個分支是所有系統開發時的正式分支,當我們初始環境架設完畢時,也都會從 main 分支開始,但是當環境架設完畢之後就會進入正式開發階段

開發階段 main

正式開發時,我們就會禁止開發者直接 commit push 到開分支,因為 main 是一個正式部署 or 正式上線中的分支。

因此當我們環境初始化部署完畢之後,就會從 main 拉出 develop 分支,而該分支接下來就只會接受其他分支的 merge 而不會有任何直接 commit 行為這非常重要。

develop

develop 是 main 分支拉出來的開發分支,該分支是我們所有開發分支基礎分支,什麼意思呢?若我們需要開發什麼功能,例如新增文章功能,就會從 develop 分支拉出 feature 分支(稍後會介紹)。

因此通常來講 main 與 develop 都會長期在 Git 上,因此這兩個又稱之為長期分支,而這個分支我們也會盡可能避免直接 commit,當功能開發完畢之後就會合併回 develop 分支,例如 feautre 合併回 develop。

代表分支名稱:develop

feature

feautre 這個分支會從 develop 拉出來,而在這邊開分支時必須注意一件事情,千萬不要直接輸入 git branch feature,如果你直接輸入這個指令還上傳到遠端儲存庫(ex: GitHub),那麼你會有很高機會被請出去喝咖啡。

主要原因是 Git 再開分支時是採用結構樹的概念去開,如果你直接建立一個分支叫做 feature 那就會導致其他人無法開立開發用的分支,因此正確開 feature 的方式是帶上斜線並命名預計要開發的功能,例如我今天要開發一個上傳功能,那麼命名就會是 git branch feature/upload

所以在開發一個專案時,你會看到一大推 feature/xxxx 是正常的。

開免錢的

而當 feature 功能開發完畢之後才會合併回去 develop。

最後你可能會說那 feature 不用刪除嗎?通常來講是不用,因為如果你刪除的話就會無法追蹤當初的分支,因此 feature 分支是不會刪除的(反正 GitHub 分支開免錢的)。

代表分支名稱:feature/xxxx,ex: feature/index

hotfix

這個分支稍微比較特別一點,這個分支通常只會在上線中的專案(main)出現 bug 時才會拉出來的,因此 hotfix 分支會直接從 main 拉出來,因此 hotfix 分支會專門針對 main 與 develop 分支修正。

而接下來當 hotfix 修正完畢之後就會直接 merge 回去到 main 與 develop 分支,那為什麼要回到 develop 分支呢?因為如果不回到 develop 分支的話,到時候 develop 回到 main 分支一樣會出現 bug。

而最後通常我們不會直接從 develop 分支拉 hotfix 出來,因為 develop 分支在前面有說過,它是屬於開發分支,如果你從這邊拉出來,許多功能都還沒完成及測試之前就 merge 回去 main 就很容易出現更嚴重的 bug。

代表分支名稱:hotfix

release

release 分支則是會從 develop 分支拉出來,而這個分支簡單來講就是正式上線前的測試分支,通常只會在 develop 準備要合併回到 main 時所使用的分支,因此 develop 會拉出 release,當測試通過時,就會將 release 合併到 main 與 develop,確保兩邊同步,所以 release 分支也會同時修正一些問題。

代表分支名稱:release

Git Flow 回顧

上面基本觀念吸收之後你就可以比較看得懂這張圖

Git Flow

當然比起文謅謅的說明,我個人會建議可以參加一些開源專案,透過實作會更清楚,因此這部分在實作上會更了解其觀念,畢竟 Git Flow 這東西說抽象是也很抽象,說不抽象也很難不抽象,而 Git Flow 有時候會因為公司性質而不同,所以這部分就要看公司自己有無自己的 Git 規範哩~

Git Commit 規範

當我們在多人開發時雖然可以透過 Git Flow 規範避免一些問題(例如:開發衝突。),但是 commit 訊息若沒有去做一些規範的話,其實在尋找一些 bug 發生點就會很困難,而且 code review 的人也會不知道你幹了哪些事情,變成必須點開程式碼一個一個去看才知道你做了什麼,所以如果你沒有一定的 commit 規範,那麼就會像我這份專案一樣

不清楚用途的 commit 訊息

雖然圖片上看起來我都有描述我做了什麼,但是當若你是多人開發時,如果每個人都是像我這樣子填寫 commit message,那麼就會搞不清楚你目前這個「加入動態路由 title」到底是新增功能還是修正功能?

因此在國外的 AngularJS 團隊就有一篇 Git Commit Message 規範

Git Commit Message Conventions

Commit 的 type

依照 AngularJS 團隊提供的規範來講,有這些 type

  • feat - 新增/修改功能 (Feature)
  • fix - 修正 Bug (bug fix)
  • docs - 修改/新增文件 (documentation)
  • style - 修改程式碼格式或風格,不影響原有運作,例如 ESLint (formatting, missing semi colons, …)
  • refactor - 重構 or 優化,不屬於 bug 也不屬於新增功能等
  • test - 增加測試功能 (when adding missing tests)
  • chore - 增加或修改第三方套件(輔助工具)等 (maintain)

透過這些 Commit Type 可以讓 Code Review 的人可以一眼明白目前這一個 commit 做了哪些事情,而觀看者也可以採用不同的心情去面對(囧,難不成你要我拿 code review 的方式去看 docs?)。

Commit 方式

接下來講講如何將 commit 規範導入到專案中,通常我們在上傳 commit message 之前都會輸入 git commit -m 'xxxx',當你導入之後你必須依照 commit 功能來改寫,例如我要新增一個上傳功能,那麼就要打 git commit -m 'feat: add to upload feature'

當然這是一個比較懶惰的方式,當你如果直接輸入 git commit 你會進入 commit 編輯階段(記得先 git add .),如下圖:

commit 編輯

依照 Git Commit Message 規範 來說,你必須將內容改成以下

1
2
3
4
5
6
7
# 這是寫文章特別新增的 commit 測試用
feat: 新增上傳功能

express add to upload feature...

# 這是搭配 GitHub 的 issues 所使用
issue #2

commit

那有可能會有人不知道該如何編輯,其實這是 vi 編輯器,因此要按下英文間的 「I」(代表:insert),輸入完畢之後按下「:」號按鈕在輸入 wq 就可以儲存上傳 commit 了。

w > 儲存
q > 退出

接下來當你上傳到遠端儲存庫時就可以看到這樣子的詳細內容,並且對應到特定 Issues

超詳細 commit

(你會發現有加上 # 並不會呈現在 GitHub 上唷~)

除此之外在看 git log 也可以非常詳細看到這個 commit 做了哪些事情

log

當然 commit 的規範也會因為公司的不同而變化哩。

補充

其實腦袋一直記著這些 Commit 的意義是很累的,因此我有撰寫一篇「來吧!用 git-cz 讓你的 Git Commit 訊息更美一點!」的工具文章,讓你可以透過一些問答方式以及客製化方式從真正意義上來規範你使用 Commit 哩。

參考文獻

Liker 讚賞

這篇文章如果對你有幫助,你可以花 30 秒登入 LikeCoin 並點擊下方拍手按鈕(最多五下)免費支持與牡蠣鼓勵我。
或者你可以也可以請我「喝一杯咖啡(Donate)」。

Buy Me A Coffee Buy Me A Coffee

Google AD

撰寫一篇文章其實真的很花時間,如果你願意「關閉 Adblock (廣告阻擋器)」來支持我的話,我會非常感謝你 ヽ(・∀・)ノ