同一個工程項目,爲了方便管理,git 的 commit 信息最好按照一定的格式規範,以便在需要的時候方便使用。什麼是方便的時候,比如出現了一個線上 bug,所以需要回滾操作,知道了提交信息可以方便的定位問題。代碼 review 的時候也知道了該次 commit 幹了什麼,所以 commit 標準化好處很多,不再舉例。
實現
可以馬上想到的是利用 shell 結合 git hook 實現在 git commit 階段檢查輸入是否符合規範。符合就通過,不符合就終止,並給出提示信息。
規範是什麼
常見的分類有下面幾種:
- build:修改項目的的構建系統(xcodebuild、webpack、glup等)的提交
- ci:修改項目的持續集成流程(Kenkins、Travis等)的提交
- chore:構建過程或輔助工具的變化
- docs:文檔提交(documents)
- feat:新增功能(feature)
- fix:修復 bug
- pref:性能、體驗相關的提交
- refactor:代碼重構
- revert:回滾某個更早的提交
- style:不影響程序邏輯的代碼修改、主要是樣式方面的優化、修改
- test:測試相關的開發
輪子
在 github 上有 commitlint 這個項目,它可以很方便的在工程中做配置,並允許你自定義上面說的「規範」、「分類」。
commitlint:用於檢查提交信息
husky:hook 工具,用於 git-commit 和 git-push 階段。
怎麼用?
- 初始化一個 node 項目:
npm init -y
- 安裝所需依賴。
npm install --save-dev @commitlint/config-conventional @commitlint/cli husky
- 在工程根目錄下新建配置文件,名稱爲
commitlint.config.js
。 - 在 commitlint.config.js 中添加配置信息
const types = [ 'build', 'ci', 'chore', 'docs', 'feat', 'fix', 'pref', 'refactor', 'revert', 'style', 'test' ]; typeEnum = { rules: { 'type-enum': [2, 'always', types] }, value: () => types } module.exports = { extends: [ "@commitlint/config-conventional" ], rules: { 'type-case': [0], 'type-empty': [0], 'scope-empty': [0], 'scope-case': [0], 'subject-full-stop': [0, 'never'], 'subject-case': [0, 'never'], 'header-max-length': [0, 'always', 72], 'type-enum': typeEnum.rules['type-enum'] } };
- 在 package.json 文件中添加以下代碼,代碼層級跟 devDependencies 同級。
"husky": { "hooks": { "pre-commit": "echo '哈嘍,小夥伴們,在這裏可以做測試相關的邏輯哦,一般結合公司的 ci'", "commit-msg": "commitlint -E HUSKY_GIT_PARAMS", "pre-push": "echo 提交代碼前需要先進行單元測試 && 可以做測試相關" } }
上面的流程配置完成,當你在提交 commit 信息的輸入的內容,如果不符合 <type>: <subject>
規則,會終止並給出提示信息。
type 就是上面的種類;subject 就是需要提交的文字概括。比如:feature:增加搖一搖推薦酒店功能。
小說明:如果某次提交想禁用 husky,可以添加參數 –no-verify。git commit --no-verify -m "xxx"
貼個效果圖
流程說明
安裝包 husky 的時候,會在目錄 .git/hooks/
下生成一堆 shell 腳本,負責 git 的 hook。
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
這個配置告訴 git hooks,當執行 git commit -m
的時候觸發 commit-msg 鉤子,並通知 husky,從而執行 commitlint -E HUSKY_GIT_PARAMS
,實際上執行的是 ./node_modules/husky/bin/run.js
,讀取 commitlint.config.js 裏的配置,然後對我們 commit -m 裏的字符串校驗,如不通過則輸出錯誤信息並終止。
拓展篇
git commit 的幾個鉤子,也暴露出來了,所以可以結合時機做一些額外的邏輯。
- pre-commit:在 git commit 之前觸發
- commit-msg:在編寫 commit 信息的時候觸發
- pre-push:在 git push 之前觸發
所以基於上述時機,可以根據項目特點做一些別的事情。比如 code lint、unit test 代碼覆蓋率檢測、changelog 自動生成、unit test 腳本等、也可以藉此機會產生 lint 報表