-
Notifications
You must be signed in to change notification settings - Fork 2
Description
优雅的提交你的 Commit message
[TOC]
Commit message 是开发的日常操作, 写好 log 不仅有助于他人 review,还可以有效的输出 CHANGELOG,对项目的管理实际至关重要,但是实际工作中却常常被大家忽略。
希望通过本文,能够帮助大家重视和规范 Commit message 的书写。
一、起因
前段时间在做zeus cli的时候,经常浏览 vue-cli 源码,不由被其 Commit message 所吸引,清晰明了,赏心悦目。
于是就了解了一下,目前社区有多种 Commit message 的 书写规范。vue-cli 采用的是 Angular 规范,也是目前使用最广的写法,比较合理和系统化,并且有配套的工具。
二、Commit message 格式
每次提交,Commit message 都包括三个部分:Header,Body 和 Footer。
<type>(<scope>): <subject>
<BLANK LINE> // 空一行
<body>
<BLANK LINE> // 空一行
<footer>其中,Header 是必需的,Body 和 Footer 可以省略。
不管是哪一个部分,任何一行都不得超过72个字符。这是为了避免自动换行影响美观。
2.1 Header
Header 部分只有一行,包括三个字段:type(必需)、scope(可选)和subject(必需)。
(1)type
type用于说明 commit 的类别,只允许使用下面列表中的标识:
- feat:新功能(feature)
- fix:修复 bug
- docs:文档(documentation)
- style:代码格式(空格,格式,缺少分号等)
- refeactor:重构(即不是新增功能,也不是修改bug的代码变动)
- perf:性能优化(performance)
- test:单元测试、集成测试、测试用例等
- chore:对构建过程或辅助工具和库(如文档生成)的更改
(2)scope
scope用于说明 commit 影响的范围,比如model、controller、view、route、component、utils等,视项目而定。
(3)subject
subject是 commit 目的的简短描述,不超过50个字符。
- 以动词开头,使用第一人称现在时,比如 change,而不是 changed 或 changes
- 第一字母小写
- 结尾不加句号(.)
2.2 Body
Body 部分时对本次 commit 的详细描述,可以分为多行。下面是一个范例。
More detailed explanatory text, if necessary. Wrap it to
about 72 characters or so.
Further paragraphs come after blank lines.
- Bullet points are okay, too
- Use a hanging indent- 以动词开头,使用第一人称现在时,比如 change,而不是 changed 或 changes
- 应该说明代码变动的动机,以及与以前行为的对比。
2.3 Footer
Footer 部分只用于两种情况。
(1)BREAKING CHANGE(不兼容变动)
如果当前代码与上一个版本不兼容,则 Footer 部分以 BREAKING CHANGE开头,后面是对变动的描述、以及变动理由和迁移的方法。
BREAKING CHANGE: isolate scope bindings definition has changed.
To migrate the code follow the example below:
Before:
scope: {
myAttr: 'attribute',
}
After:
scope: {
myAttr: '@',
}
The removed `inject` wasn't generaly useful for directives so there should be no code using it.(2)关闭 Issue
如果当前 commit 针对某个 issue,那么可以在 Footer 部分关闭这个 issue。
Closes #234也可以一次关闭多个 issue。
Closes #234, #123, #3452.4 Revert
还有一种特殊情况,如果当前 commit 用于撤销以前的 commit,则必须以revert开头,后面跟着被撤销 Commit 的 Header。
revert: feat(pencil): add 'graphiteWidth' option
This reverts commit 667ecc1654a317a13331b17617d973392f415f02.Body 部分的格式是固定的,必须写成This reverts commit <hash>.,其中的hash 是被撤销 commit 的 SHA 标识符。
如果当前 commit 与被撤销的 commit,在同一个发布(release)里面,那么它们都不会出现在 Change log 里面。如果两者在不同的发布,那么当前 commit,会出现在 Change log 的Reverts 小标题下面。
三、项目集成
上面的规则对于未接触过的同学还是需要一些时间适应的,git commit 也是可以通过工具生成的。
3.1 Git commit 模版
当 commit message 一行不够时,可以执行git commit,就会跳出文本编辑器,让你写多行。
git commit而 git commit 模版就会在指令执行后出现。
修改~/.gitconfig(~指系统根目录),添加:
[commit]
template = ~/.gitmessage新建 ~/.gitmessage内容可以如下:
# head: <type>(<scope>): <subject>
# - type: feat, fix, docs, style, refactor, test, chore
# - scope: can be empty (eg. if the change is a global or difficult to assign to a single component)
# - subject: start with verb (such as 'change'), 50-character line
#
# body: 72-character wrapped. This should answer:
# * Why was this change necessary?
# * How does it address the problem?
# * Are there any side effects?
#
# footer:
# - Include a link to the ticket, if any.
# - BREAKING CHANGE
#实际操作:
3.1 使用 Commitizens 代替你的 git commit
通过工具生成 commit message。
commitzen/cz-cli,借助它提供的git cz命令代替git commit命令,询问式的生成符合规范的 commit message。
除此之外,我们还需要为 commitizen 指定一个 Adapter 比如:cz-conventional-changelog(一个符合 Angular 团队规范的 preset),使得 commitizen 按照我们指定的规范帮助我们生成 commit message。
(1)全局安装
npm install -g commitizen cz-conventional-changelog
echo '{ "path": "cz-conventional-changelog" }' > ~/.czrc在全局模式下,新增~/.csrc配置文件,为 commitzens 指定 Adapter。
(2)项目安装
npm install -D commitizen cz-conventional-changelogpackage.json 中配置:
"script": {
...,
"ct": "git add . && git-cz",
},
"config": {
"commitizen": {
"path": "node_modules/cz-conventional-changelog"
}
}如果全局安装过 commitizen,那么在对应的项目中执行git cz或npm run ct都可以。
项目局部安装,无法使用git cz,可以使用npm run ct,建议全局安装。
效果如下:
(3)自定义 Adapter
也许 Angular 的那套规范我们不习惯, 那么可以通过指定 Adapter cz-customizable 指定一套符合自己团队的规范。
# 全局安装
npm i -g cz-customizable
# 项目安装
npm i -D cz-customizable修改 ~/.czrc 或 package.json 中的 config 为:
// ~/.czrc
{ "path": "cz-customizable" }
// package.json 中 config
"config": {
"commitizen": {
"path": "node_modules/cz-customizable"
}
}同时在~/ 或项目目录下创建 .cz-config.js 文件, 维护自定义格式。
3.2 Commitlint 校验你的 message
上面是通过工具生成 commit message,当然我们还是可以通过:
# git commit -m "type(scope): subject"
git commit -m "docs(readme): 修改readme"这种方式直接提交。commitlint,可以辅助 lint commit message,如果提交的 message 不符合指向的规范,则不能提交代码。
安装:
npm i -D @commitlint/config-conventional @commitlint/cli同时需要在项目目录下创建配置文件.commitlintrc.js,写入:
module.exports = {
extends: ['@commitlint/config-conventional'],
// rules 中的内容可自定义,当前与 @commitlint/config-conventional 一致
// 用于查看可自定义项
rules: {
// body 以空行开头
'body-leading-blank': [1, 'always'],
// footer 以空行开头
'footer-leading-blank': [1, 'always'],
// header 最大长度 72 个字符
'header-max-length': [2, 'always', 72],
// 提交影响范围
'scope-case': [1, 'always', 'lower-case'],
// 提交内容
'subject-case': [2, 'always', 'lower-case'],
// 提交内容不能为空
'subject-empty': [2, 'never'],
// 提交内容不能以 . 结尾
'subject-full-stop': [2, 'never', '.'],
// 提交类型案例
'type-case': [2, 'always', 'lower-case'],
// 提交类型不能为空
'type-empty': [2, 'never'],
// 支持的提交类型
'type-enum': [
2,
'always',
[
'build',
'chore',
'ci',
'docs',
'feat',
'fix',
'perf',
'refactor',
'revert',
'style',
'test'
]
]
}
}(1)针对自定义 Adapter 进行 Lint
如果使用自定义的commitizen adapter,那么你需要:
npm i -D commitlint-config-cz @commitlint/cli.commitlintrc.js 中写入:
module.exports = {
extends: [
'cz'
],
rules: {
}
}3.3 Husky 集成
校验 commit message 的最佳方式是结合git hook,目前大前端主要有两种 git 钩子插件 husky(jQuery,babel,create-react-app,Next.js等在用) 和 pre-commit(antd等在用)。
这里推荐Husky的原因:
- pre-commit 没有 husky 全面,可以大致理解为 pre-commit 是 husky 子集。
- pre-commit 在集成的过程中,替换了 git commit 的默认行为,使得整套工作流需要处理较多兼容问题,处理麻烦。
- 官方推荐集成 husky。
npm i husky -Dpackage.json 中添加
"husky": {
"hooks": {
...
"pre-commit": "npm run lint", // commmit 前执行代码检查
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}效果如下:
3.4 Standard-version:自动生成 CHANGELOG
通过以上工具的帮助, 我们的工程 commit message 应该是符合 Angular 团队那套, 这样也便于我们借助 standard-version 这样的工具, 自动生成 CHANGELOG。
安装使用:
npm i -D standard-versionpackage.json 配置:
"scirpt": {
...,
"release": "standard-version"
}
standard-version 有许多其他的特性,详情请看官网介绍。
效果如下:
会在项目根目录下生成一个CHANGELOG.md的文件,如下所示:
以上图片为测试数据。
建议将feat,fix,以及BREAKING CHANGE放在 changelog 中。其他情况(docs、chore、style、refactor、test),具体视项目而定,建议不要。
四、最后
这样一个符合规范的 commit message,就好像一封邮件。关于 commit message 每个团队和个人都有自己的想法,个人认为:好的习惯,受益终身。






