反對 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-by或Issue-ID),將主旨行留給人類可讀的英文描述。