告别 fix bug!拯救Git Commit Log的规范
哈喽,大家好呀,我是呼噜噜,在企业软件开发工作中,常常使用 Git
来管理代码,每当我们对代码进行改动时,都需要通过 git commit
来对代码提交,说明本次提交的目的,什么改动等
但在实际开发中,如果团队没有规定,提交的 commit message
千奇百怪;或者就自己一个人独立开发,那必须"怎么快怎么来",结果项目复杂度上来后,出问题的那一刻,看着提交记录满屏的
"fix bug"
"fix bug"
"fix bug"
...
完全看不出来,每个提交的"fix bug"修改的是什么问题? 再看下提交人 呵 竟然是自己!!! 只能熬夜加班~
所以良好规范的 commit
,能够提升提交记录的可读性
和自动化处理能力
,帮助我们review代码,问题排查和版本追溯。还能够通过一些工具(如 standard-version
),自动生成版本变动内容,Github
上许多开源项目就是这么处理的。从长远来看,编写良好规范的 commit
,可以提高代码维护效率和质量。
Conventional Commits 规范
如今比较流行的Git
规范是Conventional Commits,它是一套基于 Git
提交消息的轻量级约定,旨在通过结构化格式提升提交信息的可读性和自动化处理能力。引导开发者在提交时思考并明确表达变更的性质、范围和影响。
这是一套被 Angular、Vue
等顶级开源项目广泛采用的 Git
提交规范,它的核心目标包括:
- 人类可读:清晰描述提交的意图和影响范围。
- 机器友好:支持自动化生成
CHANGELOG
和语义化版本(SemVer
)。 - 团队协作:统一提交风格,减少沟通成本。
提交消息的结构应如下所示:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
type
其中type
代表的是提交内容的一种类型,必写,每一种类型都代表着不同的含义,具体的类型取值和含义如下
feat
:表示开发一个新的需求特性fix
:表示修复一个 bugrefactor
:不是进行feat
和fix
的代码修改,重构功能perf
:优化相关,比如提升性能、体验docs
:表示是针对文档的修改,并没有修改代码style
:格式修改,不影响代码功能test
:添加测试代码或者修正已经存在的测试功能代码chore
:一些不够影响到源码和测试文件的修改ci
:用于提交CI配置文件和脚本的修改build
:修改会影响构建或者依赖的代码release
:发布新版本revert
:针对之前的一个提交的 回滚- ...
scop
scope
,表示commit
影响的范围,可写但推荐,若涉及范围较大,可用 *
代替,比如: route
, component
, utils
...
例如:feat(auth): add JWT authentication
,表示在 auth
模块中新增了 JWT
身份验证功能
subject
subject
表示 commit
的概述,必写,标题简述修改,结尾不要有句号
例如:fix: correct typo in README
,表示修复了 README
文件中的拼写错误
body
body
表示 commit
具体说明修改的内容, 可以分为多行,可选
例如: feat: 新增用户管理功能
footer
footer
脚释,可选,用于记录与提交相关的其他信息,如关联的任务、问题或破坏性变更。它通常以 BREAKING CHANGE:
开头,后跟详细说明。脚注也可以包含引用的 issue
编号或链接
BREAKING CHANGE:
- 更新了 API 接口,删除了 `getUser` 方法,改为 `fetchUser`。
- 需要更新客户端代码以适应新接口。
Closes #123
Review by @zhangsan
重大变更
重大变更 必须 通过在 type/scope
前缀中添加 !
或在 footer
中使用 BREAKING CHANGE:
来指明。
如果使用了 !
,则 BREAKING CHANGE: footer
是可选的,提交描述将用作变更的说明
例如:refactor!(auth): remove deprecated JWT authentication method
注意:这里的 !
表明这是一个破坏性变更,即使type
是refactor
约定式提交规范
- 每个提交都必须使用类型字段前缀,它由一个名词组成,诸如
feat
或fix
,其后接一个可选的作用域字段,以及一个必要的冒号(英文半角)和空格。 - 当一个提交为应用或类库实现了新特性时,必须使用
feat
类型。 - 当一个提交为应用修复 bug 时,必须使用
fix
类型。 - 作用域字段可以跟随在类型字段后面。作用有必须是一个描述某部分代码的名词,并用圆括号包围,例如:
fix(parser):
- 描述字段必须紧接在类型/作用域前缀的空格之后。描述指的是对代码变更的简短总结,例如:
fix:array parsing issue when multiplejspaces were contained in string
。 - 在简短描述之后,可以编写更长的提交正文,为代码变更提供额外的上下文信息。正文必须起始于描述字段结束的一个空行后。
- 在正文结束的一个空行之后,可以编写一行或或多行脚注。脚注必须包含关于提交的元信息,例如:关联的合并请求、Reviewer、破坏性变更、每条元信息一行。
- 破坏性变更必须标示在正文区域最开始处,或脚注区域中某一行的开始。一个破坏性变更必须包含大写的文本
BREAKING CHANGE
,后面紧跟冒号和空格。 - 在
BREAKING CHANGE:
之后必须提供描述,以描述对 API 的变更。例如:BREAKING CHANGE: enviroment variables now take precedence over cofig files
。 - 在提交说明中,可以使用
feat
和fix
之外的类型。 - 工具的实现必须不区分大小写地解析构成约定式提交的信息单元,只有
BREAKING CHANGE
必须是大写的。 - 可以在类型/作用域前缀之后,
:
之前,附加!
字符,以进一步提醒注意破坏性变更。当有!
前缀时,正文或脚注内必须包含BREAKING CHANGE: description
为什么要使用 Conventional Commits?
- 我们先回顾一些,常见的提交信息不规范情况以及痛点:
1. 混乱的提交信息是常态:
`fix bug`(修复了什么 bug?)
`update`(更新了什么?)
`asdf`(毫无意义)
大段无结构描述(难以快速抓住重点)
2. 大型项目/团队的痛点:
难以从 `git log` 快速理解项目演进。
定位引入 bug 或特定功能的提交如同大海捞针。
代码审查 (`code review`) 效率低下。
自动化流程(如生成变更日志)难以实现。
- 提交信息的好处:
- 自动生成
Change Log
:轻松跟踪项目的更改历史和版本更新 - 自动确定语义版本更新:根据提交类型自动确定版本更新(
fix
对应PATCH
,feat
对应MINOR
,BREAKING CHANGE
对应MAJOR
) - 将变更的性质传达给团队成员、公众和其他利益相关者,更清晰的沟通
- 触发自动构建和发布流程
- 使开发者更容易理解和遵循项目规范,使开发者更容易为您的项目做出贡献
常用的工具帮助指引更好的落地
Commitizen
: 交互式命令行工具,引导用户创建符合规范的提交信息。Commitlint
: 用于校验提交信息是否符合规范,常与Git Hooks
(如 husky) 集成,可以在提交时自动检查规范,确保团队规范落地执行- 自动化版本与
Changelog
工具: 如semantic-release
,goreleaser/chglog
等 IDE
插件: 主流 IDE (VS Code
,JetBrains IDEs
等) 均有插件提供模板、补全和校验支持。
尾语
Conventional Commits
不仅是技术规范,更是团队协作的沟通协议。它可以引导我们的每一次git commit
不再是随意的记录,而是对项目演进负责任的、有意义的贡献。
参考:
https://www.conventionalcommits.org/en/v1.0.0
作者:小牛呼噜噜
本文到这里就结束啦,感谢阅读,关注同名公众号:小牛呼噜噜,防失联+获取更多技术干货