Cz工具集使用介紹 - 規範Git提交說明

子弈發表於2019-04-27

在多人協作的專案中,如果Git的提交說明精準,在後期協作以及Bug處理時會變得有據可查,專案的開發可以根據規範的提交說明快速生成開發日誌,從而方便開發者或使用者追蹤專案的開發資訊和功能特性。

本文主要內容:

  • 介紹符合Angular規範(需要翻牆)的提交說明
  • 介紹提交說明工具集cz(介面卡、校驗以及日誌)的使用方法
  • 介紹供開發者快速生成專案cz工具集的Vue CLI 3外掛@ziyi2/ui-cz

這裡提供演示專案地址:cz-example

Git的提交說明

Git每次提交程式碼的時候都需要手寫提交說明(Commit message):

git commit -m "hello world"
複製程式碼

書寫多行可以使用以下命令:

git commit
複製程式碼

此時會跳出一個文字編輯器,可以在文字編輯器中書寫多行提交說明

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# Your branch is up to date with 'origin/master'.
#
# Changes to be committed:
#       new file:   package.json
#
G:/git-lab/cz/.git/COMMIT_EDITMSG [unix] (19:49 24/01/2019)   
複製程式碼

如果沒有規範的提交說明,很難闡述當前程式碼的提交性質(修復Bug、程式碼效能優化、新增功能或者釋出版本等)。檢視Vue專案的Git提交說明fix表明修復問題、feat表明新增功能...),它完全符合Angular規範:

enter image description here

手寫符合規範的提交說明很難避免錯誤,可以藉助工具來實現規範的提交說明

規範的Git提交說明

  • 提供更多的歷史資訊,方便快速瀏覽
  • 可以過濾某些commit,便於篩選程式碼review
  • 可以追蹤commit生成更新日誌
  • 可以關聯issues

Git提交說明結構

Git提交說明可分為三個部分:HeaderBodyFooter

<Header> <Body> <Footer>
複製程式碼

Header

Header部分包括三個欄位type(必需)、scope(可選)和subject(必需)。

<type>(<scope>): <subject>
複製程式碼

Vue原始碼的提交說明省略了scope

type

type用於說明 commit 的提交性質。

描述
feat 新增一個功能
fix 修復一個Bug
docs 文件變更
style 程式碼格式(不影響功能,例如空格、分號等格式修正)
refactor 程式碼重構
perf 改善效能
test 測試
build 變更專案構建或外部依賴(例如scopes: webpack、gulp、npm等)
ci 更改持續整合軟體的配置檔案和package中的scripts命令,例如scopes: Travis, Circle等
chore 變更構建流程或輔助工具
revert 程式碼回退

scope

scope說明commit影響的範圍。scope依據專案而定,例如在業務專案中可以依據選單或者功能模組劃分,如果是元件庫開發,則可以依據元件劃分。

提示:scope可以省略。

subject

subjectcommit的簡短描述。

Body

commit的詳細描述,說明程式碼提交的詳細說明。

Footer

如果程式碼的提交是不相容變更關閉缺陷,則Footer必需,否則可以省略。

不相容變更

當前程式碼與上一個版本不相容,則FooterBREAKING CHANGE開頭,後面是對變動的描述、以及變動的理由和遷移方法。

關閉缺陷

如果當前提交是針對特定的issue,那麼可以在Footer部分填寫需要關閉的單個 issue 或一系列issues。

Commitizen

commitizen/cz-cli是一個可以實現規範的提交說明的工具:

When you commit with Commitizen, you'll be prompted to fill out any required commit fields at commit time. No more waiting until later for a git commit hook to run and reject your commit (though that can still be helpful). No more digging through CONTRIBUTING.md to find what the preferred format is. Get instant feedback on your commit message formatting and be prompted for required fields.

提供選擇的提交資訊類別,快速生成提交說明。安裝cz工具:

npm install -g commitizen
複製程式碼

Commitizen介面卡

cz-conventional-changelog

如果需要在專案中使用commitizen生成符合AngularJS規範的提交說明,初始化cz-conventional-changelog介面卡:

commitizen init cz-conventional-changelog --save --save-exact
複製程式碼

如果當前已經有其他介面卡被使用,則會報以下錯誤,此時可以加上--force選項進行再次初始化

Error: A previous adapter is already configured. Use --force to override
複製程式碼

初始化命令主要進行了3件事情

  1. 在專案中安裝cz-conventional-changelog 介面卡依賴

  2. 將介面卡依賴儲存到package.jsondevDependencies欄位資訊

  3. package.json中新增config.commitizen欄位資訊,主要用於配置cz工具的介面卡路徑:

"devDependencies": {
 "cz-conventional-changelog": "^2.1.0"
},
"config": {
  "commitizen": {
    "path": "./node_modules/cz-conventional-changelog"
  }
}
複製程式碼

接下來可以使用cz的命令git cz代替git commit進行提交說明

enter image description here

程式碼提交到遠端的Github後,可以在相應的專案中進行檢視,例如(這裡使用feat不是很合適,只是一個示例):

enter image description here

cz-customizable

如果想定製專案的提交說明,可以使用cz-customizable介面卡:

Suitable for large teams working with multiple projects with their own commit scopes. When you specify the scopes in your .cz-config.js, cz-customizable allows you to select the pre-defined scopes. No more spelling mistakes embarrassing you when generating the changelog file.

安裝介面卡

npm install cz-customizable --save-dev

將之前符合Angular規範的cz-conventional-changelog介面卡路徑改成cz-customizable介面卡路徑:

"devDependencies": {
  "cz-customizable": "^5.3.0"
},
"config": {
  "commitizen": {
    "path": "node_modules/cz-customizable"
  }
}
複製程式碼

cz-customizable will first look for a file called .cz-config.js,alternatively add a config block in your package.json。

官方提供了一個.cz-config.js示例檔案cz-config-EXAMPLE.js,如下所示:

'use strict';

module.exports = {

  types: [
    {value: 'feat',     name: 'feat:     A new feature'},
    {value: 'fix',      name: 'fix:      A bug fix'},
    {value: 'docs',     name: 'docs:     Documentation only changes'},
    {value: 'style',    name: 'style:    Changes that do not affect the meaning of the code\n            (white-space, formatting, missing semi-colons, etc)'},
    {value: 'refactor', name: 'refactor: A code change that neither fixes a bug nor adds a feature'},
    {value: 'perf',     name: 'perf:     A code change that improves performance'},
    {value: 'test',     name: 'test:     Adding missing tests'},
    {value: 'chore',    name: 'chore:    Changes to the build process or auxiliary tools\n            and libraries such as documentation generation'},
    {value: 'revert',   name: 'revert:   Revert to a commit'},
    {value: 'WIP',      name: 'WIP:      Work in progress'}
  ],

  scopes: [
    {name: 'accounts'},
    {name: 'admin'},
    {name: 'exampleScope'},
    {name: 'changeMe'}
  ],

  // it needs to match the value for field type. Eg.: 'fix'
  /*
  scopeOverrides: {
    fix: [
      {name: 'merge'},
      {name: 'style'},
      {name: 'e2eTest'},
      {name: 'unitTest'}
    ]
  },
  */
  // override the messages, defaults are as follows
  messages: {
    type: 'Select the type of change that you\'re committing:',
    scope: '\nDenote the SCOPE of this change (optional):',
    // used if allowCustomScopes is true
    customScope: 'Denote the SCOPE of this change:',
    subject: 'Write a SHORT, IMPERATIVE tense description of the change:\n',
    body: 'Provide a LONGER description of the change (optional). Use "|" to break new line:\n',
    breaking: 'List any BREAKING CHANGES (optional):\n',
    footer: 'List any ISSUES CLOSED by this change (optional). E.g.: #31, #34:\n',
    confirmCommit: 'Are you sure you want to proceed with the commit above?'
  },

  allowCustomScopes: true,
  allowBreakingChanges: ['feat', 'fix'],

  // limit subject length
  subjectLimit: 100
  
};
複製程式碼

這裡對其進行漢化處理(只是為了說明定製說明的一個示例):

'use strict';

module.exports = {

  types: [
    {value: '特性',     name: '特性:    一個新的特性'},
    {value: '修復',      name: '修復:    修復一個Bug'},
    {value: '文件',     name: '文件:    變更的只有文件'},
    {value: '格式',    name: '格式:    空格, 分號等格式修復'},
    {value: '重構', name: '重構:    程式碼重構,注意和特性、修復區分開'},
    {value: '效能',     name: '效能:    提升效能'},
    {value: '測試',     name: '測試:    新增一個測試'},
    {value: '工具',    name: '工具:    開發工具變動(構建、腳手架工具等)'},
    {value: '回滾',   name: '回滾:    程式碼回退'}
  ],

  scopes: [
    {name: '模組1'},
    {name: '模組2'},
    {name: '模組3'},
    {name: '模組4'}
  ],

  // it needs to match the value for field type. Eg.: 'fix'
  /*
  scopeOverrides: {
    fix: [
      {name: 'merge'},
      {name: 'style'},
      {name: 'e2eTest'},
      {name: 'unitTest'}
    ]
  },
  */
  // override the messages, defaults are as follows
  messages: {
    type: '選擇一種你的提交型別:',
    scope: '選擇一個scope (可選):',
    // used if allowCustomScopes is true
    customScope: 'Denote the SCOPE of this change:',
    subject: '短說明:\n',
    body: '長說明,使用"|"換行(可選):\n',
    breaking: '非相容性說明 (可選):\n',
    footer: '關聯關閉的issue,例如:#31, #34(可選):\n',
    confirmCommit: '確定提交說明?'
  },

  allowCustomScopes: true,
  allowBreakingChanges: ['特性', '修復'],

  // limit subject length
  subjectLimit: 100

};
複製程式碼

再次使用git cz命令進行提交說明

enter image description here

從上圖可以看出此時的提交說明選項已經漢化,繼續填寫提交說明

enter image description here

把程式碼提交到遠端看看效果:

enter image description here

Commitizen校驗

commitlint

校驗提交說明是否符合規範,安裝校驗工具commitlint

npm install --save-dev @commitlint/cli
複製程式碼

@commitlint/config-conventional

安裝符合Angular風格的校驗規則

npm install --save-dev @commitlint/config-conventional 
複製程式碼

在專案中新建commitlint.config.js檔案並設定校驗規則:

module.exports = {
  extends: ['@commitlint/config-conventional']
};
複製程式碼

安裝huksy(git鉤子工具)

npm install husky --save-dev
複製程式碼

在package.json中配置git commit提交時的校驗鉤子:

"husky": {
  "hooks": {
    "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
  }  
}
複製程式碼

需要注意,使用該校驗規則不能對.cz-config.js進行不符合Angular規範的定製處理,例如之前的漢化,此時需要將.cz-config.js的檔案按照官方示例檔案cz-config-EXAMPLE.js進行符合Angular風格的改動。

執行錯誤的提交說明:

enter image description here

執行符合Angular規範的提交說明:

enter image description here

commitlint需要配置一份校驗規則,@commitlint/config-conventional就是符合Angular規範的一份校驗規則。

commitlint-config-cz

如果是使用cz-customizable介面卡做了破壞Angular風格的提交說明配置,那麼不能使用**@commitlint/config-conventional**規則進行提交說明校驗,可以使用commitlint-config-cz對定製化提交說明進行校驗。

安裝校驗規則:

npm install commitlint-config-cz --save-dev
複製程式碼

然後加入commitlint校驗規則配置:

module.exports = {
  extends: [
    'cz'
  ]
};
複製程式碼

這裡推薦使用**@commitlint/config-conventional**校驗規則,如果想使用cz-customizable介面卡,那麼定製化的配置不要破壞Angular規範即可。

validate-commit-msg

除了使用commitlint校驗工具,也可以使用validate-commit-msg校驗工具對cz提交說明是否符合Angular規範進行校驗。

Commitizen日誌

如果使用了cz工具集,配套conventional-changelog可以快速生成開發日誌:

npm install conventional-changelog -D
複製程式碼

pacage.json中加入生成日誌命令:

"version": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md"
複製程式碼

You could follow the following workflow

  • Make changes
  • Commit those changes
  • Pull all the tags
  • Run the npm version [patch|minor|major] command
  • Push

執行npm run version後可檢視生產的日誌CHANGELOG.md

注意要使用正確的Headertype,否則生成的日誌會不準確,這裡只是一個示例,生成的日誌不是很嚴格。

Vue CLI 3 外掛

如果對於上述所說的配置感到繁瑣,這裡提供一個Vue CLI 3的外掛,如果開發的專案由Vue CLI 3系統生成,可以使用外掛@ziyi2/ui-cz一鍵生成:

vue add @ziyi2/ui-cz
複製程式碼

該外掛採用了cz-customizable定製化提交說明的介面卡、@commitlint/config-conventional校驗規則以及conventional-changelog日誌生成器。

總結

呼籲大家書寫規範的提交說明,程式碼說明不規範,專案成員淚兩行。演示專案地址:cz-example

連結

相關文章