Git 版本控制 協作流程指南 深入解析 Atomic Commit、Conventional Commits 與 Git Flow 最佳實踐

me
林彥成
2022-09-29 | 8 min.
文章目錄
  1. 1. 如何在團隊中實踐高品質的 Git 協作流程?
  2. 2. Git 版本控制:專案開發的時光機
  3. 3. 為什麼要使用 Git 版本控制:軟體工程的核心價值
    1. 3.1. Git 初始化專案
  4. 4. Git 協作實戰:原子化、約定式提交與合併請求
    1. 4.1. 原子化提交 (Atomic Commit):降低耦合與優化追蹤
    2. 4.2. 約定式提交 (Conventional Commits):自動化版號管理的規範
      1. 4.2.1. 語意化版本
    3. 4.3. 合併請求 (Pull Request):高品質的程式碼審查流程
      1. 4.3.1. PR 合併策略
  5. 5. Git Flow 與 GitHub Flow:高效的分支管理模型
  6. 6. FAQ:Git 版本控制與協作常見問題
    1. 6.1. Q1:什麼是原子化提交 (Atomic Commit),為什麼它對前端開發很重要?
    2. 6.2. Q2:約定式提交 (Conventional Commits) 如何協助專案管理?
    3. 6.3. Q3:在團隊開發中,Rebase 與 Merge 合併策略該如何選擇?

如何在團隊中實踐高品質的 Git 協作流程?

Git 版本控制實戰 的核心在於建立一套清晰、可追蹤且低耦合的開發秩序。高品質的 專案協作流程 包含:1. 原子化提交 (Atomic Commit):將每個 commit 限制在單一功能,降低還原風險;2. 約定式提交規範 (Conventional Commits):透過 feat:fix: 等前綴,協助自動化工具生成語意化版號 (SemVer);3. 高品質 Pull Request (PR):提供明確的測試步驟與技術見解;4. 分支策略 (Git Flow):區分長期分支(Master, Develop)與短期分支(Feature, Hotfix)。掌握這些 軟體工程最佳實踐,能顯著提升程式碼審查效率,讓 Git 成為專案開發中最強大的時光機。


Git 版本控制:專案開發的時光機

Git 本身是一個分散式(一個遠端和很多本地端)的 版本控制系統 (VCS)。它會把每次提交的內容 (commit) 用快照透過校驗碼標示並儲存起來。校驗碼概念上可以當成車廂號碼,讓我們可以隨時查看特定版本中的檔案及狀態。掌握 Git 版本控制 是現代工程師的必備技能。

實際運作上,Git 比較像資料結構中的 Linked List,透過改變指標可以回到某個狀態,也可以自由地切割和移動節點。這份 專案協作與開發指南 將帶您深入了解其中的奧秘。

本日結果 -> 昨日結果 -> 前日結果

紀錄每個提交的項目主要會包含:

  • Commit: 可以想成是指標
  • Parents: 會指向前一個 commit
  • Author: 用戶名稱
  • Date: 日期

可以透過 git log 指令來查看過去紀錄:

1
2
3
4
5
6
7
8
9
Commit ea8ccbae1371612578d7f4711719f56c1e425ed9
Parents 0e5acdc487a5974fad9563c1a301dc3bbf58ea2c
Author: LinYenCheng <linyencheng.tw@gmail.com>
Date: Wed Sep 28 21:59:16 2022 +0800

Commit 0e5acdc487a5974fad9563c1a301dc3bbf58ea2c
Parents a1e45318a3eb15c18685ccdcb036bb42892e5627
Author: LinYenCheng <linyencheng.tw@gmail.com>
Date: Wed Sep 28 21:07:40 2022 +0800

為什麼要使用 Git 版本控制:軟體工程的核心價值

人生就是不斷在後悔中持續成長

生命中的每個不同階段總有不少事情,會讓我們後悔當時怎麼沒有去做。在 軟體工程 中,Git 版本控制 提供了「後悔藥」的功能,讓我們能夠追蹤歷史、還原錯誤並優化架構。

比如你各位!!!當年學生時期喜歡上的那個男孩或女孩,為什麼當時就不懂得好好珍惜和努力?!說個我喜歡你很困難嗎?!

時光飛逝幾年過去,也許喜歡的那個誰已經有了小孩,而你,卻還在魯,這樣魯下去可以嗎?是不是很想回到過去?

雖然人生沒有辦法版本控制也沒辦法回到從前,但寫程式可以,到了專案不同的階段,也許也會想要再次回頭嘗試看看過去的解決方案。

  • 使用前: 用資料夾版本控制
  • 使用後: 除了版本訊息外更提供了切割和移動等進階功能

在個人開發上我們可以用來取代之前開資料夾的方式,還原也更為方便。

常見且小編使用過的版控服務有

Git 初始化專案

首先要先安裝 Git,專案目錄輸入 git init 初始化版本控制,接著 git add . 加入所有目錄中相關檔案並執行 git commit 進行提交即可。

Git 協作實戰:原子化、約定式提交與合併請求

專案協作 或是跟團體共同開發程式時,為了減少衝突的發生並希望開發流程順暢,我們會遵循一系列的原則。這就是 Git 版本控制 在團隊開發中的實戰應用。

分支其實就是在快照上面新增一個指標,叫做分支的名稱,名稱就會指向那個校驗碼,方便切換過去。

1
2
3
4
5
本日結果1 - 昨日結果 - 前日結果
| |
本日結果2 -----   |
|
本日結果3 --------------

開源專案或是跟團體共同協作程式時,為了減少衝突的發生也希望大家都盡可能不受影響的開發,我們會希望大家都遵守一些流程和原則:

  • 原子化提交 (Atomic Commit): 減少每個 commit 耦合,未來在還原或拆掉時也不需要確認太多事情。
  • 約定式提交 (Conventional Commits): 方便之後 release 的統整。
  • 合併請求 (Pull Request): 團隊成員的 commit 都會以 PR 當單位進入長期分支中。
  • Git Flow 與 GitHub Flow: 按照團隊的規則讓 commit 們去到該去的地方。

原子化提交 (Atomic Commit):降低耦合與優化追蹤

原子化提交 的概念在許多地方都很適用,尤其是在 前端網頁設計 上。我們建議將每個 commit 限制在單一功能或修復中,這能有效降低程式碼耦合,讓未來的還原或重構更加輕鬆。

一個好的 commit 紀錄就是將這些東西按照步驟實作的過程,在前端專案,通常會是 component-based 的元件,所以元件或頁面的 commit 就會包含組成的過程。

  • Layout
  • theme or style
  • render 邏輯
  • 資料串接

以上面的例子來說,如果未來我們需要抽換主視覺,我們是不是就可以找到 theme style 的 commit 來進行複習修改即可?

約定式提交 (Conventional Commits):自動化版號管理的規範

約定式提交 規範是在程式碼提交時按照一組簡單的規則來建立明確的提交歷史。透過這種規範,自動化工具能協助我們產生語意化的版號,大幅提升 專案管理 的效率。

當然如果只有自己開發也沒有想要理解自己過去的歷史,那當然訊息可以隨便打個字元就好了。

當規範出現後,相關支援 SemVer 的自動化工具就能協助進行整理成語意化的版號,並且透過版號能夠看出背後的意涵。

訊息格式會像這樣 類型(範圍): 敘述,範圍通常用檔名,所以一個 commit 訊息可能會是:

BREAKING CHANGE(README.md): 影響功能

常用類型:

  • fix(pencil): 什麼竟然有 typo
  • feat(pencil): 加入橡皮擦變成擦擦筆
  • perf(pencil): 2B 寬度變兩倍

其他可能有機會用到的:

  • docs: 文件
  • refactor: 重構
  • revert: 復原
  • style: 長相風格相關,不影響功能
  • test: 測試功能
  • chore: 打雜類的工作

語意化版本

語意化的版本號碼通常會有三個數字,舉例來說 v1.2.3 就代表 vMajor.Minor.Patch

  • Major: 寫法或 API 可能不相容前一個版本
  • Minor: 加了新的 feature 通常不影響前一個版本
  • Patch: 修 bug 不影響前一個版本

回想我們升級相關套件的時候,是不是都會去看別人的 release note 或是 change log,當我們的 commit 都有規則,我們可以使用工具幫我們輕鬆做好這件事。

合併請求 (Pull Request):高品質的程式碼審查流程

當完成功能實作後,我們透過 合併請求 (Pull Request, PR) 與遠端分支同步。高品質的 PR 應包含預備知識、注意事項與測試步驟,這是確保 程式碼審查 (Code Review) 質量的關鍵。

當我們撰寫 PR 時,Review 程式碼的人可能是新人也可能很久沒看這部分,所以 PR 中盡可能去提供:

  • 預備知識
  • 需要特別注意的地方
  • 有沒有未來可改善的 // TODO:
  • 測試步驟

有時候團隊成員其實不知道你怎麼會選擇這個解決方案,所以時間又更允許的話,可以盡可能提供當下的想法和見解給大家知道。

畢竟有的時候我們只有當下的最佳解,有的時候時間只夠我們 make it work,這時候就很適合留個 // TODO:,等到未來有空的時候大家知道可以 Make it right 甚至 Make it fast。

前同事 J: 當考慮解決方案的時候,想想每個解法的利弊,可以從更多面向看到不同的優缺點

狀態好的時候可以學著追求完美,至於狀態不好的時候,完整就謝天了,一個好的 PR

  • 理論上只能有相關的 commit
  • 每個 commit 最好不要更動太多檔案,會難以閱讀

前同事 W: 專案合作上,盡量保持多想想怎麼讓團隊每個人都舒服

當我們操作失當的時候,可能會發現 PR 中出現了很多不必要的 commit,其中一個原因可能是因為太久沒有跟遠端分支同步的關係,這時候:

同事可能 OS: 乾,你那什麼 PR,裡面一堆東西,我已經很忙了,這他媽一堆 commit 是要看三小??!

好同事可能就會提醒你說,沒關係不要緊張,因為好的 commit 紀錄是可以做出來的。

Commit 只需要東拼西湊整理好即可,當我們發現現在版本跟測試機或是正式機 (master) 差異過大時,有兩種方式

  1. 重新從 master 開新分支,一個個把需要的 commit 抓進來 (cherry-pick)
  2. 以 master 當 base 重新往下長我們的 commit,這就是 rebase 的用法

過程中也可以透過 rebase 互動模式拔掉 (drop) 或合併一些 (squash) 不想要的 commit,把現在的分支經過整理之後,重新發一個或是回去看看我們的 PR 這時候肯定就會發現真的整齊了不少,底下推薦三個常用指令

  1. 拆掉已經加上去的 Commit: git reset --soft HEAD~1,數字表示移動到 HEAD 後面第幾個
  2. 把其他的 Commit 抓過來: git cherry-pick ea8ccba
  3. 整理 Commit: git rebase -i ea8ccba

PR 合併策略

  1. Merge: 忠實紀錄完整呈現,但有時候線圖會穿插較不整齊且不易閱讀。
  2. Squash: 有一派的說法是當功能完成後,過去的 commit 都不重要,合併進去時就是一個 commit 紀錄我們完成了什麼功能即可。
  3. Rebase: 將起點移到最新,才進行合併,線圖會較整齊。

Git Flow 與 GitHub Flow:高效的分支管理模型

將程式碼加入 Git 版本控制 後,合理的 分支策略 (Branching Strategy) 是維持開發秩序的關鍵。Git FlowGitHub Flow 是目前業界最主流的分支管理模型。

原則上主要分支是不會也不可以被協作者直接操作的,Git Flow 還建議專案 可以有其他分支如下:

  • master: 長期存在的主要分支,可以看成是正式網站
  • develop: 長期存在的開發分支,可以看成是測試站台
  • hotfix: 短期分支,解完 bug 合併後可以看情況移除
  • release: 短期分支,需要一點時間合併幾個 feature 才要一起 release
  • feature: 短期分支,短期開發的小功能

當團隊開發時,情境如果是如果是新的 feature,然後大概一周內會合併進去 develop 我們就會:

  1. 先評估我們的東西屬於哪個類別 (feature),之後要進到哪個分支 (develop)
  2. 從 develop 開一個影分身的短期分支叫做 feature
  3. 團隊就會以 feature 為準,並在個人本機端上的開分支進行開發
  4. 個人分配的 feature 開發結束後,每個 Pull Request 都會對 feature 送
  5. 當經過團隊 review 之後就可以被 merge 進去 feature
  6. 所有的 feature 完成並測試後,再以 feature 分支對 develop 發 release 到測試站的 PR
  7. 測試無誤後就正式 release 到正式站

其實也有一說是當 CI/CD 及測試穩定時,如果產品版本不分散的話,團隊只需要一個 Master,任何改動及修改都對 Master 即可。


FAQ:Git 版本控制與協作常見問題

Q1:什麼是原子化提交 (Atomic Commit),為什麼它對前端開發很重要?

A:原子化提交 是指每個 commit 只包含一個邏輯上的修改(如:僅修改樣式、僅新增一個 API 介接)。這在 前端網頁設計 中尤為重要,因為前端程式碼常涉及視覺與邏輯的交織。如果一個 commit 同時修改了 10 個檔案且包含 3 個功能,當其中一個功能出錯需要 Revert 時,會非常難以拆分。高品質的原子化提交能讓 程式碼審查 更有焦點。

Q2:約定式提交 (Conventional Commits) 如何協助專案管理?

A:約定式提交規範 提供了一種標準化的語法(如 feat:, fix:)。這讓開發者一眼就能看出提交的本質。更重要的是,它能配合工具(如 Semantic Release)自動根據 commit 類型決定版本號的增量(Major/Minor/Patch),並自動生成高品質的 Change Log,大幅減少手動撰寫發布日誌的負擔。

Q3:在團隊開發中,Rebase 與 Merge 合併策略該如何選擇?

A:這取決於團隊對「線圖整潔度」的要求。Merge 會保留完整的歷史分岔,雖然真實但較凌亂。Rebase 能將您的開發歷史「接」在目標分支的最新處,產生一條線性的歷史,極具閱讀性。然而,Git Rebase 教學 的關鍵提醒是:千萬不要對已經推送到遠端的公共分支執行 Rebase,這會導致協作者的歷史錯亂。建議在個人分支整理完畢後再以 Rebase 合併。



喜歡這篇文章,請幫忙拍拍手喔 🤣