Git Commit 團(tuán)隊(duì)規(guī)范限制

由于近半年來接觸到的項(xiàng)目中Git Commit都沒有做限制聚凹,不規(guī)范的Git Commit提交使得現(xiàn)有項(xiàng)目的Git Log雜亂無章驰弄。長(zhǎng)此以往乾闰,當(dāng)我們需要項(xiàng)目復(fù)盤比庄、code review或者日常查詢以往功能的時(shí)候分不清哪些是新功能求妹、哪些是修復(fù)bug等等。

例如佳窑,我們?cè)?021年開發(fā)了一個(gè)功能,后來由于項(xiàng)目不再需要此功能從代碼中刪除了父能。在2022年的時(shí)候其他需求中也用到了這個(gè)功能神凑,這時(shí)候如果我們沒有一個(gè)合理的git commit提交規(guī)范,以目前的git commit描述是很難找到這個(gè)功能的代碼的何吝。尤其是在多人協(xié)作的團(tuán)隊(duì)項(xiàng)目中溉委,這種弊端更為明顯。
因此規(guī)范團(tuán)隊(duì)的提交是非常有必要的爱榕,所以git commit規(guī)范約束就特別需要了瓣喊。

以下為一個(gè)無commit message規(guī)范的git提交記錄,可以看到commit message沒有規(guī)范約束黔酥,可隨意錄入任何內(nèi)容藻三,無論它與提交內(nèi)容是否一致。


無規(guī)范的commit message

所以我們今天要說的就是為commit message提供一個(gè)約束跪者,使我們的提交信息更為規(guī)范棵帽,能夠一目了然的知道我們這次提交是什么內(nèi)容。
下面這張圖是經(jīng)過git commit規(guī)范約束后的commit message:


commit message規(guī)范約束后的git提交記錄

我們可以看到此條message的大致格式為:<type>(<scope>): <subject>渣玲,下面將會(huì)詳細(xì)介紹git commit規(guī)范的格式和檢測(cè)工具的具體配置方式逗概。

Commit Message格式

要想規(guī)范git commit 提交,我們先要了解一下Commit Message格式忘衍,目前規(guī)范使用較多的是 Angular 團(tuán)隊(duì)的規(guī)范, 這是目前使用最廣的寫法逾苫,比較合理和系統(tǒng)化。繼而衍生了 Conventional Commits specification. 很多工具也是基于此規(guī)范, 它的 message 格式如下:

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer></footer>

Commit message 都包括三個(gè)部分:Header枚钓,Body 和 Footer铅搓,其中,Header 是必需的秘噪,Body 和 Footer 可以省略狸吞。不管是哪一個(gè)部分,任何一行都不得超過100個(gè)字符。這是為了避免自動(dòng)換行影響美觀蹋偏。

由于Body和Footer不是必需的便斥,我們?nèi)粘S玫降囊脖容^少,這里不再多做闡述威始,我們重點(diǎn)介紹一下Header部分枢纠。
Header部分只有一行,包括三個(gè)字段:type(必需)黎棠、scope(可選)和subject(必需)晋渺。注意冒號(hào)后面有空格

  1. type(必填)
    type用于說明 commit 的類別。
 * feat:新增功能
 * fix:bug 修復(fù)
 * docs:文檔更新
 * style:不影響程序邏輯的代碼修改(修改空白字符脓斩,格式縮進(jìn)木西,補(bǔ)全缺失的分號(hào)等,沒有改變代碼邏輯)
 * refactor:重構(gòu)代碼(既沒有新增功能随静,也沒有修復(fù) bug)
 * perf:性能, 體驗(yàn)優(yōu)化
 * test:新增測(cè)試用例或是更新現(xiàn)有測(cè)試
 * build:主要目的是修改項(xiàng)目構(gòu)建系統(tǒng)(例如 glup八千,webpack,rollup 的配置等)的提交
 * ci:主要目的是修改項(xiàng)目繼續(xù)集成流程(例如 Travis燎猛,Jenkins恋捆,GitLab CI,Circle等)的提交
 * chore:不屬于以上類型的其他類型重绷,比如構(gòu)建流程, 依賴管理
 * revert:回滾某個(gè)更早之前的提交
  1. scope(可選)
    scope用于說明 commit 影響的范圍沸停,比如數(shù)據(jù)層、控制層昭卓、視圖層等等愤钾,視項(xiàng)目不同而不同。

  2. subject(必填)
    subject是 commit 目的的簡(jiǎn)短描述葬凳。

  • 以動(dòng)詞開頭绰垂,使用第一人稱現(xiàn)在時(shí),比如change火焰,而不是changed或changes劲装;
  • 第一個(gè)字母小寫;
  • 結(jié)尾不加句號(hào)(.)

使用commitlint工具來檢驗(yàn)commit格式是否符合規(guī)范

上面我們已經(jīng)了解了Commit Message的格式是什么樣的了昌简,如果讓我們自己手動(dòng)敲出那些格式也不是不可能占业,但是我們都知道人工輸入難免會(huì)有失誤的時(shí)候,我們借助commitlint工具進(jìn)行commit格式是否符合規(guī)范纯赎。

  1. 安裝commitlint cli
npm install --save-dev @commitlint/config-conventional @commitlint/cli
  1. 配置commitlint使用傳統(tǒng)的config配置文件
    可以在項(xiàng)目根目錄使用命令行生成(如下所示)谦疾,也可以直接在根目錄手動(dòng)創(chuàng)建commitlint.config.js文件
echo module.exports = {extends: ['@commitlint/config-conventional']} > commitlint.config.js

自動(dòng)生成的配置文件采用commitlint默認(rèn)的配置,如下所示:

module.exports = { extends: ['@commitlint/config-conventional'] };

當(dāng)然犬金,你也可以配置rules念恍,自定義規(guī)則:

module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [
      2,
      'always',
      ['feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore', 'revert']
    ],
    'subject-full-stop': [0, 'never'],
    'subject-case': [0, 'never'],
    'header-max-length': [0, 'always', 72]
  }
};

rule配置說明:rule由name和配置數(shù)組組成六剥,如:name:[0, 'always', 72]

  • 數(shù)組中第一位為level峰伙,可選0疗疟、1、2瞳氓。0為禁用策彤,1為警告,2為錯(cuò)誤匣摘;
  • 第二位為應(yīng)用與否店诗,可選always|never;
  • 第三位該rule的值音榜。

Git Hooks

commitlint本身只是一個(gè)檢測(cè)工具庞瘸,想要讓它真正發(fā)揮作用,需要與git hooks相結(jié)合赠叼。而husky 是一個(gè) Git Hook 工具恕洲,一個(gè)為 git 客戶端增加 hook 的工具,husky繼承了Git下所有的鉤子梅割,在觸發(fā)鉤子的時(shí)候,husky可以阻止不合法的commit葛家,push等等户辞。這里我分需要分成三個(gè)部分來講解:

Husky5.0版本以下,以4.3.8為例

  1. husky安裝
npm install husky --save-dev
  1. 把commitline配置到githook鉤子中癞谒,如果package.json文件中已經(jīng)配置了husky底燎,直接追加上去即可,如果沒有配置弹砚,則添加以下代碼
"husky": {
    "hooks": {
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
},

這段配置告訴了git hooks双仍,當(dāng)我們?cè)诋?dāng)前項(xiàng)目中執(zhí)行 git commit -m '測(cè)試提交'時(shí)將觸發(fā)commit-msg事件鉤子并通知husky,從而執(zhí)行commitlint -E HUSKY_GIT_PARAMS命令桌吃,也就是我們剛開始安裝的 ./node_modules/.bin/ commitlint朱沃,它將讀取commitlint.config.js配置規(guī)則并對(duì)我們剛剛提交的“測(cè)試提交”這串文字進(jìn)行校驗(yàn),若校驗(yàn)不通過茅诱,則在終端輸出錯(cuò)誤逗物,commit終止。
使用commit-msg給出了我們想要的東西:只要?jiǎng)?chuàng)建新的提交就會(huì)執(zhí)行它瑟俭。傳遞husky的 HUSKY_GIT_PARAMS 給 commitlint 通過 -E|--env 標(biāo)記它引導(dǎo)到相關(guān)的編輯文件翎卓。-E默認(rèn)為 .git/COMMIT_EDITMSG 。

commit message不符合規(guī)范

commit message不符合規(guī)范
commit message符合規(guī)范

從上面三張圖片中可以看到摆寄,當(dāng)手動(dòng)提交git commit -m “aaa”git commit -m “abc: aaaaa”時(shí)失暴,由于不符合規(guī)則坯门,就會(huì)報(bào)錯(cuò),不通過了逗扒。只有把必填的都寫上古戴,符合規(guī)則才可以通過。

Husky5.0版本以上缴阎,以7.0.4為例

我們有時(shí)候會(huì)發(fā)現(xiàn)允瞧,按照以上步驟配置完成后 git commit的時(shí)候還是沒有效果,沒有去執(zhí)行husky配置的鉤子蛮拔。因?yàn)镠usky升級(jí)到5.0版本以上后述暂,在配置上與4.x版本有所差別,按上面的配置只適用于4.x建炫,這里簡(jiǎn)要概況一下畦韭。

  1. 依然需要先安裝husky,由于現(xiàn)在husky版本已經(jīng)7.x了肛跌,如果不指定版本艺配,默認(rèn)安裝的是最新版本,這里我們使用官方推薦的自動(dòng)安裝的的方式衍慎,你也可以選擇使用傳統(tǒng)方式分步安裝转唉,具體步驟在這里:husky傳統(tǒng)安裝步驟
npx husky-init && npm install

安裝后觀察package.json文件,如果版本高于5.0稳捆,那么就用這個(gè)單元里的方案

"husky": "^7.0.4",

并且項(xiàng)目根目錄下會(huì)多一個(gè).husky文件夾赠法,里面會(huì)有個(gè)pre-commit文件,這個(gè)文件就是在commit之前會(huì)執(zhí)行的一個(gè)Hook(這里可以打開pre-commit文件看一下乔夯,如果默認(rèn)里面是npm test砖织,把他刪除掉,不然后面會(huì)報(bào)錯(cuò))


自動(dòng)安裝husky后生成的pre-commit鉤子文件
  1. 配置commit-msg鉤子
    執(zhí)行以下命令末荐,在生成的commit-msg文件中手動(dòng)鍵入npx --no-install commitlint --edit "$1"(這里已經(jīng)試過侧纯,按照官方提供的方式直接執(zhí)行npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'命令無法生成commit-msg文件)
npx husky add .husky/commit-msg

完成以上兩個(gè)步驟以后,就可以去git commit測(cè)試一下是否已經(jīng)配置完成甲脏。當(dāng)然眶熬,我們也可以去pre-commit文件下配置一下代碼過濾工具。

vue-cli創(chuàng)建的項(xiàng)目中的gitHooks

在使用 vue create xxx 創(chuàng)建項(xiàng)目的時(shí)候剃幌,Vue 會(huì)自動(dòng)幫我們做好一些預(yù)配置聋涨,其中就有一個(gè)叫做yorkie的包,這個(gè)包是尤大 fork 自husky?的负乡,它倆功能是一樣的牍白,都是生成一些 git hooks 文件,讀取項(xiàng)目中 package.json 的相關(guān)配置項(xiàng)去執(zhí)行一些命令抖棘,區(qū)別是尤大做了一些邏輯和配置上的改動(dòng)茂腥。
yorkie的流程解析就不在這里細(xì)說狸涌,感興趣的可以自行去網(wǎng)上查詢資料,總之最岗,在使用vue-cli創(chuàng)建的項(xiàng)目中可以不安裝husky帕胆,直接配置gitHooks,當(dāng)然你也可以使用husky的方式般渡,這沒有任何問題懒豹,一切根據(jù)個(gè)人習(xí)慣而定。

下面講一下在vue項(xiàng)目中配置gitHooks的另一種方式:在vue-cli創(chuàng)建的環(huán)境中使用gitHooks是非常簡(jiǎn)單的驯用,只需要commitlint cli安裝安成后脸秽,在package.json文件中直接通過字段直接添加git鉤子即可。

"gitHooks": {
     "commit-msg": "commitlint -E GIT_PARAMS"
},

這里我們拓展一下知識(shí)點(diǎn)蝴乔,我們知道commit-msg是一個(gè)git鉤子记餐,當(dāng)然除了commit-msg,git還有很多的其他的鉤子薇正,現(xiàn)在我們就來聽過pre-commit這個(gè)鉤子來配置一下代碼過濾工具片酝,以防止不小心把錯(cuò)誤的代碼提交到git上。

  1. 安裝lint-staged挖腰,這里用到的lint-staged版本為10.2.11雕沿,建議不要隨意改動(dòng)版本
npm install lint-staged --save-dev
  1. 在package.json中定義gitHooks
"gitHooks": {
    "pre-commit": "lint-staged",
    "commit-msg": "commitlint -E GIT_PARAMS"
},
  1. 配置前端文件過濾工具lint-staged猴仑,這里用了vue-cli-service晦炊,當(dāng)然你也可以選擇用eslint等代碼檢測(cè)工具。
"lint-staged": {
    "*.{js,vue}": [
      "vue-cli-service lint",
      "git add"
    ]
},
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末宁脊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子贤姆,更是在濱河造成了極大的恐慌榆苞,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件霞捡,死亡現(xiàn)場(chǎng)離奇詭異坐漏,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)碧信,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門赊琳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人砰碴,你說我怎么就攤上這事躏筏。” “怎么了呈枉?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵趁尼,是天一觀的道長(zhǎng)埃碱。 經(jīng)常有香客問我,道長(zhǎng)酥泞,這世上最難降的妖魔是什么砚殿? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮芝囤,結(jié)果婚禮上似炎,老公的妹妹穿的比我還像新娘。我一直安慰自己悯姊,他們只是感情好羡藐,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著挠轴,像睡著了一般传睹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上岸晦,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天欧啤,我揣著相機(jī)與錄音,去河邊找鬼启上。 笑死邢隧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的冈在。 我是一名探鬼主播倒慧,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼包券!你這毒婦竟也來了纫谅?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤溅固,失蹤者是張志新(化名)和其女友劉穎付秕,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體侍郭,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡询吴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了亮元。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片猛计。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖爆捞,靈堂內(nèi)的尸體忽然破棺而出奉瘤,到底是詐尸還是另有隱情,我是刑警寧澤煮甥,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布毛好,位于F島的核電站望艺,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏肌访。R本人自食惡果不足惜找默,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吼驶。 院中可真熱鬧惩激,春花似錦、人聲如沸蟹演。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酒请。三九已至骡技,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間羞反,已是汗流浹背布朦。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留昼窗,地道東北人是趴。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像澄惊,于是被迫代替她去往敵國和親唆途。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容