Git規(guī)范實(shí)踐

規(guī)范說明

git commit message即代碼提交歷史,錯(cuò)誤的提交信息會(huì)影響代碼的可維護(hù)性。在多人協(xié)作開發(fā)場(chǎng)景下因個(gè)人風(fēng)格各有不同,若無統(tǒng)一的規(guī)范則很容易導(dǎo)致混亂。目前規(guī)范使用較多的是 Angular 團(tuán)隊(duì)的規(guī)范

消息提交格式

每個(gè)提交消息都包含一個(gè)header、body、footerheader具有一種特殊的格式,其中包括type,scopesubject

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

為使在各種git工具中更易于閱讀,提交消息的任何一行都不能超過100個(gè)字符。

Header

  • type
    必須為以下之一開頭:

    • feat:一項(xiàng)新的功能feature
    • fix: bug修復(fù)
    • docs: 只修改了文檔
    • style: 沒有代碼的更改,樣式調(diào)整(空白,格式,缺少分號(hào)等)
    • refactor: 代碼重構(gòu),既不修正bug也不增加功能(feature)的更改
    • perf: 改進(jìn)性能的代碼更改
    • test: 添加缺失或更正現(xiàn)有測(cè)試
    • build: 影響構(gòu)建系統(tǒng)或外部依賴項(xiàng)的更改,如:gulp, broccoli, npm
    • ci: 對(duì)CI配置文件和腳本的更改,如:Travis,Circle,BrowserStack,SauceLabs
    • chore: 更改構(gòu)建過程或輔助工具和庫,例如文檔生成等
    • revert: 如果該提交還原了先前的提交,則應(yīng)以revert:開頭 ,后接reverted commitheader。此外body中應(yīng)該標(biāo)明:This reverts commit <hash>,其中hash是要還原的提交的SHA值。
  • scope
    scope是可選的。
    用于輔助說明所要提交代碼更改的內(nèi)容歸屬,例如可以指明是哪個(gè)位置(location)、哪個(gè)模塊(module)、哪個(gè)組件(componet)等。當(dāng)更改影響的范圍不止一個(gè)范圍時(shí),可以使用*。

  • subject
    該主題包含對(duì)變更的簡(jiǎn)潔描述:
    使用現(xiàn)在時(shí)態(tài):“change”不是“ changed”也不是“ changes”
    不要大寫第一個(gè)字母
    末尾沒有點(diǎn)(。)

Body

就像在主題(subject)中一樣,使用命令式現(xiàn)在時(shí)態(tài):“change”而不是“changed”或“changes”。 body應(yīng)包括改變的動(dòng)機(jī),并將其與以前的行為進(jìn)行對(duì)比。

Footer

  • 不兼容變動(dòng)
    如果當(dāng)前代碼與上一個(gè)版本不兼容,則 Footer 部分以 BREAKING CHANGE 開頭,用空格或兩個(gè)換行符,后面是對(duì)變動(dòng)的描述、以及變動(dòng)理由和遷移方法。如fix并攜帶BREAKING CHANGE信息:
fix: correct spelling of referrer in header

BREAKING CHANGE: Rather than using misspelled "Referer" as name of header,
instead use correct spelling "Referrer". Clients expecting "Referer" will no
longer receive that header  and will presumably not honor the new "Referrer"
until updated to support this new name for this header.
  • 關(guān)閉 Issue
    如果當(dāng)前 commit 針對(duì)某個(gè)issue,那么可以在 Footer 部分關(guān)閉這個(gè)關(guān)聯(lián)issue 。
Closes #123

或者關(guān)閉多個(gè)issue

Closes #123 #456 #789

GitHub關(guān)聯(lián)issue說明:https://docs.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue

項(xiàng)目配置

現(xiàn)在比較流行的方案是約定式提交規(guī)范(Conventional Commits),它受到了 Angular 提交準(zhǔn)則的啟發(fā),并在很大程度上以其為依據(jù)。筆者嘗試查找了基于非node環(huán)境相關(guān)的Git規(guī)范化的輔助工具或插件,并沒有找到很好的解決方案,而我們?nèi)绻麚碛衝ode環(huán)境非node項(xiàng)目也可以正常配置執(zhí)行,只不過在工程中會(huì)生成node項(xiàng)目相關(guān)的文件,如node_modules文件夾、package.json文件等,因此在項(xiàng)目的版本控制中稍微麻煩一些,根據(jù)需要定義自己的ingore文件,處理好項(xiàng)目代碼和環(huán)境代碼的問題。

環(huán)境和工具

  • node
  • npm(npx)
  • commitizen/cz-cli: 是一個(gè)格式化commit message的工具,可以約束提交者按照制定的規(guī)范一步一步的填寫commit message。
  • cz-conventional-changelog: 為 commitizen 指定一個(gè) Adapter ,一個(gè)符合 Angular 團(tuán)隊(duì)規(guī)范的 preset(按照我們指定的規(guī)范幫助我們生成 commit message)

非node項(xiàng)目

定位到workspace目錄(即項(xiàng)目根目錄)命令行輸入npm init,執(zhí)行后會(huì)出現(xiàn)一系列初始化的提示,可以一直回車至結(jié)束。npm init 相關(guān)說明:https://www.npmjs.cn/cli/init/

依賴安裝

  • 安裝commitizencz-conventional-changelog
npm i -D commitizen
npm i -D cz-conventional-changelog
  • 修改package.json文件
    工程的配置示例.png
{
  "name": "testp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "commit": "git-cz"
  },
  "config": {
    "commitizen": {
      "path": "node_modules/cz-conventional-changelog"
    }
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "commitizen": "^4.2.3",
    "cz-conventional-changelog": "^3.3.0"
  }
}

在項(xiàng)目根目錄,命令行執(zhí)行npm run commit,會(huì)出現(xiàn)操作步驟提示,按前文所訴填寫規(guī)范化信息。

操作提示.png

操作提示..png

執(zhí)行完,sourcetree效果圖:
效果圖.png

Commit信息校驗(yàn)和攔截

雖然我們?cè)陧?xiàng)目中配置了commit,但是如果我執(zhí)行規(guī)范操作,不使用npm run commit提交代碼,通過命令行或者Git可視化工具直接commit,那么提交上去的可能是不規(guī)范的信息,因此需要對(duì)git命令進(jìn)行攔截,并對(duì)message內(nèi)容做lint操作。

  • lint工具依賴安裝
    • commitlint/cli 【命令行工具】
    • commitlint/config-conventional 【校驗(yàn)規(guī)則】符合 Angular團(tuán)隊(duì)規(guī)范。
npm i -D @commitlint/config-conventional @commitlint/cli
  • 修改 package.json,配置commitlint
{
   ...
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "commit": "git-cz",
    "commit-lint": "commitlint -e $HUSKY_GIT_PARAMS"
  },
  "config": {
    "commitizen": {
      "path": "node_modules/cz-conventional-changelog"
    }
  },
  "commitlint": {
    "extends": [
      "@commitlint/config-conventional"
    ]
  },
  ...
}
  • 安裝Husky,進(jìn)行git hooks校驗(yàn)
  npm install husky --save-dev
  • 啟用git hooks
npx husky install 

git hooks啟用后會(huì)在項(xiàng)目根目錄下生產(chǎn).husky的文件夾

image.png

  • 添加commit_msg到husky,用于攔截git commit命令
npx husky add .husky/commit-msg "npm run commit-lint"

執(zhí)行完成后會(huì)生成commit-msg的腳本

commit-msg-shell.png

此時(shí)我們?cè)诿钚兄苯訄?zhí)行git commit -m "test message",會(huì)被攔截提示提交失敗。
image.png

SourceTree的問題

通過上面配置完成后用SourceTree提交代碼會(huì)發(fā)現(xiàn)運(yùn)行錯(cuò)誤。

image.png

這是因?yàn)镾ourceTree沒有讀取到環(huán)境變量信息,需要在commit-msg腳本中添加環(huán)境變量的配置。
image.png

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

export PATH=/usr/local/bin:$PATH
npm run commit-lint --silent

此刻再運(yùn)行,已成功攔截


image.png

說明

  • cz-conventional-changelog提交信息提示和@commitlint/config-conventionallint規(guī)則都可以設(shè)置自定義的Adapter,可以根據(jù)自己需要配置適合自己團(tuán)隊(duì)的規(guī)范。
  • 文章截圖是以非node(Android)項(xiàng)目的視角進(jìn)行的配置,其他項(xiàng)目也類似,只要使用的Git進(jìn)行的版本控制,都可以實(shí)現(xiàn)Commit Message的規(guī)范化校驗(yàn)。
  • 文章依賴的是Mac OS,Windows下類似,所有的依賴庫在Windows下也可運(yùn)行工作,只不過環(huán)境的配置方式不同而已。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容