如何配置 Git Commit Message

如何配置 Git Commit Message

一、背景

好的 commit message,能够在多人协作的大型项目中,快速定位代码提交历史,回溯问题根源,提高团队效率。

commit message 是提交代码过程中的log,属于项目管理中一个重要的环节。

我们以前端 React 生态体系为例:

路由】:react-router /  react-router-redux等
状态管理】:flux reduxmobx等
UI库】:materialmaterial-uireact-toolbox等
工具】:Immutabledraft-jscss-modulesReact Devtoolsbabeles6es7)、typescript
项目构建】:webpackfis3gulp等
代码规范】:editorconfigeslintprettier等
提交规范】:commit-lintcommit-message等
// 当然还有移动生态 例如:react-native

而今天我们要讨论的 commit message 属于 提交规范 这一基础环节。

下图是 React 的 commit message,非常清晰。


二、stock overflow 上的建议

Git Commit Messages : 50/72 Formatting (提交信息接近限制在50到72个字符)

三、commit message

3.1 目的

在阅读代码时,可以通过 commit message 了解到作者编写某行代码时的背景;
回溯 bug 时可以通过搜索 commit message 快速定位相关的提交记录。
最重要的是养成好的习惯,提高团队和个人工作效率。
  • 提供明确的历史信息(方便快速浏览)
  • 可以过滤某些不必要的提交(方便快速查找)
  • 自动化生成 Changelog(自动化)
  • 基于提交的类型(分类)

3.2 基础指令

Workspace:工作区
Index / Stage:暂存区
Repository:仓库区(或本地仓库)
Remote:远程仓库


// 提交工作区自上次commit之后的变化,直接到仓库区
$ git commit -a [message] 

// 提交暂存区到仓库区
$ git commit -m [message]

3.3 安装依赖

第一步:替代 git commit

  • commitizen/cz-cli: 替代你的 git commit(帮助我们生成符合规范的 commit message)
// [推荐全局安装] commitizen 为我们提供一些 cli 命令
// 比如:commitizen init、 git cz

$ npm install commitizen -g
  • cz-conventional-changelog: 是一个commitizen的 adapter(适配器),一个符合 Angular 团队规范的 preset(按照我们指定的规范帮助我们生成 commit message)
// 有两种安装方式

// 1.手动安装 [推荐]
$ yarn add cz-conventional-changelog -D

// 2.自动安装
commitizen init cz-conventional-changelog --save-dev --save-exact
配置 package.json
{
    "scripts": {
        "commit": "git-cz"
    },
    "config": {
        "commitizen": {
          "path": "node_modules/cz-conventional-changelog"
        }
    }
}


如果我们需要自定义 adapter

  • cz-customizable:可自定义的Commitizen插件。比如:默认的提交 types 可能特别多,有些时候我们可能只需要其中的某些 type,或者自定义type。
$ yarn add cz-customizable -D
配置 package.json
{
    "config": {
        "commitizen": {
          "path": "node_modules/cz-customizable"
        }
    }
}
在根目录下,配置 .cz-config.js
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: '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:     Add missing tests or correcting existing tests'
    },
    {
      value: 'build',
      name : 'build:    Add missing tests or correcting existing tests'
    },
    {
      value: 'revert',
      name : 'revert:   Revert to a commit'
    }
  ],
  allowBreakingChanges: ['feat', 'fix', 'refactor', 'perf', 'build', 'revert']
};


第二步:校验 commit

commitlint 帮我们规范 commit messagecommitlint的实现方式和commitizen差不多也需要个 adapter)

  • @commitlint/cli 【命令行工具】
  • @commitlint/config-conventional 【校验规则】符合 Angular团队规范(不同于代码规范),当然还有其它规范。
// [推荐局部安装]
$ yarn add @commitlint/config-conventional @commitlint/cli -D 
package.json 配置
"commitlint": {
    "extends": [
      "@commitlint/config-conventional"
    ]
  }

也可以

在根目录下使用配置文件: .commitlintrc.js
module.exports = {
  extends: ['@commitlint/config-conventional']
}


针对自定义的 Adapter 进行 Lint

如果是使用cz-customizable适配器做了破坏 Angular 风格的提交说明配置,那么不能使用@commitlint/config-conventional规则进行提交说明校验,可以使用commitlint-config-cz 对定制化提交说明进行校验。

安装校验规则:

npm i -D commitlint-config-cz @commitlint/cli

此时的 .commitlintrc.js 文件:

module.exports = {
  extends: [
    'cz'
  ]
};


第三步: Husky

在提交代码前通常我们会通过eslint等工具来校验 我们的代码,然后再进行提交,由于 git 提供了 hook机制,所以我们可以通过 git hook pre-commit 进行 eslint,在 commit-msg 阶段进行 commit message lint

3.1 pre-commit

配合 Husky 进行 git hook 校验

// 安装
$ npm install husky --save-dev
配置 package.json
"husky": {
    "hooks": {
      "pre-commit": "lint-staged",
      "commit-msg": "commitlint -e $GIT_PARAMS"
    }
}
或者,使用配置文件:.huskyrc
{
  "hooks": {
    "pre-commit": "lint-staged",
    "commit-msg": "commitlint -e $GIT_PARAMS"
  }
}


3.2 lint-staged

当我们运行eslint或stylelint的命令时,只会检查我们通过git add添加到暂存区的文件,可以避免我们每次检查都把整个项目的代码都检查一遍。

$ yarn add lint-staged -D

配置 package.json

{
    // ....
    "husky": {
        "hooks": {
          "pre-commit": "lint-staged",
          "commit-msg": "commitlint -e $GIT_PARAMS"
        }
    },
    "lint-staged": {
        "src/**/*.{tsx,ts}": [
          "prettier --write",
          "git add"
        ]
    }
    // ...
}

第四步:standard-version

以上配置已经可以满足提交代码的常规要求,但是如果我们想自动生成 CHANGELOG,语义化我们的版本(Semantic Versioning)。 就需要借助 standard-version

standard-version的作用就是生成 changelog 更新 package.json 和 package.lock.json 中的 version 字段。

关于版本:

// 版本
major主版本号不兼容的API修改
minor次版本号向下兼容功能性增加
patch修订号向下兼容bug fixed

// 版本发布进度
alpha内测
beta公测
rc 正式版本的候选版本  Release Candiate

// npm 发布指令
升级补丁版本号npm version patch
升级小版本号npm version minor
升级大版本号npm version major

关于release:

// 发布首个版本
npm run release -- --first-release

// 发布预发布版本
// 例如:v1.0.0 -> v1.0.0-0
npm run release -- --prerelease

// 发布与首个 alpha 版本 
// 例如:v1.0.0 -> 1.0.1-alpha.0
npm run release -- --prerelease alpha

// 发布 major、minor、patch 版本 
npm run release -- --release-as minor

安装

$ yarn add standard-version -D

配置 package.json

{
    "script": {
        // .....
        "release": "standard-version"
    }
}


3.4 完整的配置

package.json

"scripts": {
    // ....
    "commit": "git-cz",
    "release": "standard-version"
  },
  "config": {
    "commitizen": {
      "path": "node_modules/cz-customizable"
    }
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged",
      "commit-msg": "commitlint -e $GIT_PARAMS"
    }
  },
  "lint-staged": {
    "src/**/*.{tsx,ts}": [
      "prettier --write",
      "git add"
    ]
  },

.cz-config.js

// type: commit 的类型
// 参考:https://juejin.im/post/5afc5242f265da0b7f44bee4
// feat: 新特性
// fix: 修改问题
// docs: 文档修改
// style: 代码格式修改, 注意不是 css 修改
// refactor: 代码重构
// chore: 其他修改, 比如构建流程, 依赖管理.
// subject: commit 的概述, 建议符合  50/72 formatting
// ...
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: '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:     Add missing tests or correcting existing tests'
    },
    {
      value: 'build',
      name : 'build:    Add missing tests or correcting existing tests'
    },
    {
      value: 'revert',
      name : 'revert:   Revert to a commit'
    }
  ],
  allowBreakingChanges: ['feat', 'fix', 'refactor', 'perf', 'build', 'revert']
};

.commitlintrc.js

module.exports = {
  extends: ['@commitlint/config-conventional']
  // extends: ['cz']
  // cz 方式需要配合插件
  // yarn add commitlint-config-cz @commitlint/cli -D
}

3.5 提交代码

用 git cz 替代,git commit
$ git cz -a

[1] 选择提交类型

参考:juejin.im/post/5afc5242

[2]描述信息

参考:github.com/angular/angu

[3] 错误 commit

(前面步骤中输入了错误的文件名)

[4] 正确 commit

完整 commit
提交历史记录

当然还有使用 emoji 表情包的方式,毕竟图片比文字更加直观 ,感兴趣也可以在项目中尝试。


其它参考:

编辑于 2020-04-02 22:06

文章被以下专栏收录