# git 与 语义化规范
# Git commit
规范
# 作用
- 能加快
Code Review
的流程 - 根据
Git Commit
的元数据生成Changelog
- 后续维护者可以知道
Feature
被修改的原因
# 技术方案
其实社区有多种 Commit message
的写法规范,我们这里使用 Angular
规范,这是目前使用最广的写法。如下图所示:
# 提交的格式要求
一般提交格式的要求如下图:
# type
type
代表了某次提交的类型,比如是修复一个 bug
还是增加了一个新的 feature
。所有的type
类型如下:
feat
:新增feature
fix
:修复bug
docs
:仅仅修改了文档,比如README
、CHANGLELOG
等等style
:仅仅修改了空格、格式缩进、多行等等,不改变逻辑refactor
:代码重构,没有加新的功能或者修复bug
perf
:优化相关,比如提升性能、体验等test
:测试用例,包括单元测试、集成测试等chore
:改变构建流程,或者增加依赖库、工具等revert
:回滚到上一个版本
# Scope
scope
字段用于说明本次 commit
所影响的范围,比如视图层、数据模型或者路由模块等,是一个可选参数。
# subject
subject
字段是本次 commit
的一个概要,需要用最简洁的语言来说明本次修改的内容。
# Body
可以使用多行文本详细地说明本次提交所改动的一些细节,从而帮助后续的使用者们更好地了解代码的内容。
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
案例取自 阮一峰老师的 Commit message 和 Change log 编写指南
# Footer
Footer
部分只用于两种情况。
- 不兼容变动
如果本次的 commit
与前一个版本的代码无法兼容,那么 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.
案例取自 阮一峰老师的 Commit message 和 Change log 编写指南
- 关闭
Issue
如果当前 commit
针对某个 issue
,那么可以在 Footer
部分关闭这个 issue
。以 Close
开头,后面用 #
号标识对应的 Issue
号码。
Closes #123, #245, #992
# validate-commit-msg
我们使用 validate-commit-msg
在提交之前验证 commit
信息是否符合要求。同时我们使用 husky
来为本地开发阶段增加 precommit
钩子
# 安装
npm install validate-commit-msg husky -D
# 配置
我们在 packages.json
中新增下面几行代码:
// ...
"husky": {
"hooks": {
"commit-msg": "validate-commit-msg"
}
},
// ...
现在当我们在命令行以 git commit -m '添加代码一波'
这样的 commit
形式提交代码的时候,就会通不过:
# sourceTree
如果你使用的 sourceTree
作为 git
的提交工具,你可能会发现在命令行中是可以出现错误的,但是 sourceTree
有的时候不灵了。
git hooks
在sourceTree
有的时候会不灵,其实这不是husky
的问题,大家可以看这篇文章:Git hooks doesn't work on Source Tree,其实就是环境变量没有添加的原因
我们可以看一下 .git/husky.sh
文件,它是根据 npx
去跑相应的命令的,在 sourceTree
需要在 .git/husky.sh
的头部加上相应的环境参数,才能让 husky
正常运作:
+ # $PATH是已有目录
+ PATH=$PATH:/usr/local/bin:/usr/local
这个时候在 sourceTree
上提交钩子就会生效了。
# 其他工具
除了 validate-commit-msg
,我们其实还可以使用 commitlint
来帮我们验证 commit
是否规范,笔者在这里就不细讲了。
# Commitizen
如果你觉得自己写规范的 comment
信息太麻烦,那么你可以使用Commitizen ,这是一个是一个撰写合格 Commit message
的工具。
# 安装
npm install -g commitizen
然后,在项目目录里,运行下面的命令,使其支持 Angular
的 Commit message
格式。
commitizen init cz-conventional-changelog --save --save-exact
以后,凡是用到 git commit
命令,一律改为使用 git cz
。这时,就会出现选项,用来生成符合格式的 Commit message
。
如下图:
# 生成 changeLog
如果你的所有 Commit
都符合 Angular
格式,那么发布新版本时, Change log
就可以用脚本自动生成。我们可以借助 conventional-changelog 帮我们生成 Change log
的工具,运行下面的命令即可。
conventional-changelog -p
angular -i CHANGELOG.md -s -r 0
我们可以在 package.json
中配置相应的 scripts
命令:
"scripts": {
// ...
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0"
},
在提交发布之前运行一下这个命令就 ok
了,下图是生成的 change log
文件的例子,大家可以试一试:
# 语义化规范
我们选择 semver
来做语义化规范,它是由 github
起草的。
它是为了解决软件管理领域中的 依赖地狱 这个问题,如果你的依赖越来越多,项目越来越大的时候,就很有可能面临版本控制被锁死的风险(必须对每一个依赖包改版才能完成某次升级)。
# 优势
- 能避免出现循环依赖
- 依赖冲突介绍
下图是 react
中的依赖关系,很清晰,没有循环依赖:
# 规范格式
主版本号 MAJOR
、次版本号 MINOR
、修订号 PATCH
,版本号递增规则如下:
- 主版本号:当你做了不兼容的
API
修改, - 次版本号:当你做了向下兼容的功能性新增,
- 修订号:当你做了向下兼容的问题修正。
# 先行版本号
当要发布 大版本 或者 核心的Feature 时,但是又不能保证这个版本的功能 100% 正常。这个时候就需要通过发布 先行版本。
先行版本号可以作为发布正式版之前的版本,格式是在修订版本号后面加上一个连接号**(-)
,再加上一连串以点(.)
** 分割的标识符,标识符可以由英文、数字和连接号 ([0-9A-Za-z-])
组成。
alpha
:是内部测试版,一般不向外部发布,会有很多Bug
。一般只有测试人员使用。beta
:也是测试版(公测,或者灰度版本),这个阶段的版本会一直加入新的功能。在Alpha
版之后推出rc
:全称Release Candidate
, 系统平台上就是发行候选版本。RC
版不会再加入新的功能了,主要着重于除错。相当于git
中的release
版本。
1.0.0-alpha
1.0.0-alpha.1
1.0.0-0.3.7
1.0.0-x.7.z.92
# 实际案例
# Vue
的版本
如下图所示:
# React 版本案例
react
版本的一些注意点,为了能让开发人员更容易地测试React
的预览版,官方使用了三个独立的发布通道来正式确定React
的流程。
- Latest 是稳定的,semver React 发布的通道。这是你从 npm 安装 React 时得到的,也是你今天已经使用的通道。对于所有面向用户的 React 应用程序,请使用此通道
- Next跟踪 React 源代码库的 master 分支,下一个次要 semver 版本的候选版本,用于 React 和第三方项目之间的集成测试。
- Experimental包括实验性 API 和在稳定版本中不可用的特性。这些特性也会跟踪 master 分支,但会打开附加特性的标记。使用此通道来试用即将发布的特性。
其中所有的版本都会发布到
npm
,但只有最新的版本使用了语义版本。预览版(Next
和Experimental
通道的版本)是根据其内容的哈希值生成的版本,例如0.0.0-1022ee0ec
用于Next
版本,0.0.0-experimental-1022ee0ec
用于Experimental
版本。更多 react 版本介绍大家可以参考:为 React 预览版的未来做准备
# 相似点
- 软件的版本通常由三位组成,形如:
X.Y.Z
- 版本是严格递增的,在
vue
中是:3.0.0 -> 2.6.11 -> 2.6.10
- 在发布重要版本时,可以发布
alpha
,rc
等先行版本,react
比较特别在16.6
之后增加了预览版。 alpha
和rc
等修饰版本的关键字后面可以带上次数和meta
信息
# 定义依赖版本号
在 npm 的依赖的规则中,还有 ~
、>
、<
、=
、>=
、<=
、-
、||
、x
、X
、*
等符号;当使用 npm install XX
时,被安装的依赖的版本号前会默认加上 ^
符号。
^
:表示同一主版本号中,不小于指定版本号的版本号
`^2.2.1` 对应主版本号为 2,不小于 `2.2.1` 的版本号,比如 `2.2.1`、`2.2.2`、`2.3.0` ,
// 主版本号固定
// 当该依赖有最新版本时(eg:2.3.3),npm install 会安装最新的依赖
~
:表示同一主版本号和次版本号中,不小于指定版本号的版本号
`~2.2.1` 对应主版本号为 2,次版本号为 2,不小于 `2.2.1` 的版本号,比如 `2.2.1、2.2.2`,主版本号和次版本号固定
>
、<
、=
、>=
、<=
、-
:用来指定一个版本号范围
`>2.1`
`1.0.0 - 1.2.0`
// 注意使用 `-` 的时候,必须两边都有空格。
||
:表示或
`^2 <2.2 || > 2.3`
x
、X
、*
:表示通配符
`*` 对应所有版本号
`3.x` 对应所有主版本号为 3 的版本号
# 总结
今天这一节主要讲了 git commit
提交规范和 semver
语义化规范,当大家以后想要做一个项目,放到社区里里面给大家用的时候,这个会很有帮助。
# 相关链接
- Commit message 和 Change log 编写指南
- git commit 规范指南
- ghoos
- commitlint+husky 规范 commit 日志
- Semver(语义化版本号)扫盲
- 语义化版本(SemVer)的范围
- 为 React 预览版的未来做准备
# 示例代码
示例代码可以看这里: