反對 Conventional Commits 的理由:為什麼範圍(Scope)比類型(Type)更重要

Conventional Commits 優先考慮了錯誤的元數據

Conventional Commits 是一個實質上很差的標準,因為它優先考慮變更的類型(例如,fix, feat, chore)而非範圍(受影響的程式碼庫特定區域)。在實務中,範圍對於依賴提交日誌的利害關係人來說是最關鍵的資訊。

為什麼範圍勝過類型

對於提交歷史的主要使用者而言,了解「變更了什麼」遠比了解「如何分類」更有價值:

  • 貢獻者: 需要識別程式碼特定區域的變更,以便跟上專案的進度或在進行 rebase 時識別潛在衝突。
  • 除錯者: 搜尋觸及了發生錯誤之組件的變更。由於任何變更類型(包括 bugfixes)都可能引入錯誤,因此 type 標籤對於隔離問題毫無用處。
  • 事件響應者: 在生產環境故障期間掃描日誌,以尋找與錯誤激增相關的特定子系統(例如,auth 範圍)所做的變更。

Conventional Commits 將範圍設為選填,實際上將變更的主題視為次於其類別。此外,type 通常是多餘的;一個寫得良好的描述,例如「防止命名空間化的 SVG 風格元素被移除」,本身就已經傳達了這是一個 fix,而不需要 fix: 前綴。

自動化承諾的失敗

Conventional Commits 承諾了幾項自動化優勢,但在現實世界的軟體工程場景中往往無法實現。

自動化變更日誌(Changelogs)

直接從提交訊息中生成變更日誌會混淆兩種不同的受眾。**提交日誌(commit log)**是面向開發者的,用於追蹤程式碼庫如何演進的故事。**變更日誌(changelog)**是面向使用者的,應該從業務角度描述功能差異。

由於單一功能通常需要多次提交,自動化工具會產生雜亂且細粒度的日誌,對終端使用者來說毫無用處。此外,還原(reverts)也是個問題:還原對於開發者的歷史紀錄而言至關重要,但對使用者來說應該是不可見的,因為被還原的變更相當於從未發生過一樣。

語義化版本控制(SemVer)自動化

由於開發過程的複雜性,使用提交類型來觸發 major、minor 或 patch 版本跳號是不可靠的:

  • 還原(Reverts): 一個立即被還原的破壞性變更(breaking change)在自動化工具中可能仍會觸發 major 版本跳號。
  • 意外破壞: 微小的破壞性變更可能被誤標為 patch,導致版本控制錯誤。
  • 事後修復: 隨後的提交可能會抵消先前的破壞性變更,但自動化工具已經標記了版本跳號。

建置與發佈觸發器

根據提交類型來觸發安全性檢查或建置(例如,跳過 docs: 的檢查)存在安全風險。惡意行為者可以將引入漏洞的提交標記為 docs: fix typos 以規避自動化工具。

替代方案:帶有範圍前綴的提交

與其遵循僵化的模式,成功的規模化專案——包括 Linux, FreeBSD, Git, Go, and NixOS——都利用了帶有範圍前綴的訊息。在這些專案中,範圍是由專案的自然架構(例如,子系統、套件路徑或微服務名稱)定義的。

Project Format Example
Linux subsystem: description i2c: virtio: mark device ready before registering the adapter
Go package: description net/http/cookiejar: add godoc links
Git area: description gitlab-ci: update macOS image
FreeBSD prefix: description linuxulator: Return EINVAL for invalid inotify flags
nixpkgs pkg-name: description xwayland: 24.1.11 -> 24.1.12

社群觀點與反論點

雖然對 Conventional Commits 的批評很尖銳,但社群中的開發者對其效用提供了不同的觀點:

支持 Conventional Commits 的論點

  • CI/CD 必要性: 有人認為,對於 99% 的專案而言,自動化標記 SemVer 並在每次合併到 main 分支時發佈,其價值超過了該格式的理論缺陷。
  • 對於初級開發者的強制執行: 一些維護者使用 Conventional Commits,因為它很容易透過 pre-commit hooks 強制執行,從而防止「恐怖」或粗心的提交訊息,進入歷史紀錄。
  • 審核者期望: 一些審核者更喜歡 type 在前,因為這能讓他們在深入研究程式碼之前,立即對變更的性質進行預期管理。

反對的論點

  • 形式主義重於實質: 批評者認為,這種格式是一種「儀式感」,浪費了主旨行中寶貴的字元。

  • 上下文缺口: 幾位開發者指出,範圍(scope)或類型(type)都不如 Issue ID 或工單號碼重要,因為這提供了變更背後的「為什麼」——這是 Conventional Commits 標準中完全缺失的上下文資訊。

  • 替代元數據: 建議使用 Git trailers(頁腳)來存放機器可讀的元數據(例如 Co-authored-byIssue-ID),將主旨行留給人類可讀的英文描述。

Sources