Commit 规范
代码开发时,经常需要提交代码,提交代码时需要填写 Commit Message(提交说明),否则就不允许提交。
而在实际开发中,我发现每个研发人员提交 Commit Message 的格式可以说是五花八门,有用中文的、有用英文的,甚至有的直接填写“11111”。这样的 Commit Message,时间久了可能连提交者自己都看不懂所表述的修改内容,更别说给别人看了。
并且一个好的Commit带来的好处是显而易见的:
- 提高团队协作效率:统一的提交信息格式有助于团队成员之间的沟通和理解。
- 便于代码审查:规范的提交信息使得代码审查者能更快地理解变更的内容和目的。
- 可以基于这些 Commit Message 进行过滤查找,比如只查找某个版本新增的功能:
git log --oneline --grep "^feat|^fix|^perf" - 可以基于规范化的 Commit Message 生成 Change Log。
- 触发构建或者发布流程:比如当 type 类型为 feat、fix 时我们才触发 CI 流程。
- 确定语义化版本的版本号:比如
fix类型可以映射为PATCH版本,feat类型可以映射为MINOR版本。带有BREAKING CHANGE的 ,可以映射为MAJOR版本。
Angular规范

Angular 规范是一种语义化的提交规范(Semantic Commit Messages),所谓语义化的提交规范包含以下内容:
- 语义化的:Commit Message 都会被归为一个有意义的类型,用来说明本次 commit 的类型。
- 规范化的:Commit Message 遵循预先定义好的规范,比如 Commit Message 格式固定、都属于某个类型,这些规范不仅可被开发者识别也可以被工具识别。
基本结构
Angular commit 规范的基本结构如下:([]表示可选)
<type>[(scope)]: <subject>
<空行>
<body>
<空行>
[footer]
主要组成部分
-
类型 (type):必须是以下之一:
- feat: 新功能
- fix: 修复 bug
- docs: 文档更改
- style: 不影响代码含义的更改(空白、格式化、缺少分号等)
- refactor: 既不修复 bug 也不添加新功能的代码更改
- perf: 提高性能的代码更改
- test: 添加缺失的测试或更正现有的测试
- build: 影响构建系统或外部依赖项的更改(例如:gulp, broccoli, npm)
- ci: 对 CI 配置文件和脚本的更改
- chore: 其他不修改 src 或 test 文件的更改
-
作用域 (scope):可选,用括号包围,指定 commit 影响的范围
-
简短描述 (subject):
- 使用祈使语气,现在时态
- 不要大写第一个字母
- 结尾不要加句号
-
正文 (body):可选,应该包含更改的动机,并与以前的行为进行对比
-
脚注 (footer):可选,用于说明 Breaking Changes 或关闭 Issue


示例
-
简单的 feature 提交:
feat(user): add email verification -
带有作用域和正文的 bug 修复:
fix(auth): correct JWT token validation The previous implementation did not properly check the token expiration. This commit adds a proper check to ensure that expired tokens are rejected. -
带有 Breaking Change 的提交:
feat(api): rename user endpoint BREAKING CHANGE: The user endpoint has been renamed from `/user` to `/users`. All API calls to the old endpoint will now return a 404 error. -
关闭 Issue 的提交:
fix(dashboard): correct data rendering Closes #123
特殊规则
- Breaking Changes 必须在 footer 中注明,以 “BREAKING CHANGE:” 开头
- 如果 type 是 feat 或 fix,必须在 changelog 中出现
- 如果存在 scope,必须用括号包围:例如
feat(parser):
Conventional Commits 规范
基本结构
一个符合 Conventional Commits 规范的提交消息应该是这样的:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
主要组成部分
-
类型 (type):描述本次提交的类型,必须是以下类型之一:
- feat: 新功能
- fix: 修复 bug
- docs: 文档更新
- style: 代码格式修改,不影响代码逻辑
- refactor: 代码重构,既不修复 bug 也不添加新功能
- perf: 性能优化
- test: 添加或修改测试用例
- build: 构建系统或外部依赖项的更改
- ci: 持续集成的配置文件和脚本的更改
- chore: 其他不修改源代码与测试文件的更改
-
作用域 (scope):可选,用于说明 commit 影响的范围,比如数据层、控制层、视图层等等
-
描述 (description):简短描述,不超过 50 个字符
-
正文 (body):可选,对本次 commit 的详细描述,可以分成多行
-
脚注 (footer):可选,用于关闭 Issue 或破坏性变更的描述
示例
-
简单提交:
feat: 添加用户登录功能 -
带作用域的提交:
fix(auth): 修复登录验证的 bug -
带正文和脚注的提交:
feat: 允许用户配置登录选项 现在用户可以选择记住登录状态,也可以选择使用双因素认证。 BREAKING CHANGE: 登录 API 的接口已更改,不再兼容旧版本。
协作规范
提交频率
如果是个人项目,随意 commit 可能影响不大,但如果是多人开发的项目,随意 commit 不仅会让 Commit Message 变得难以理解,还会让其他研发同事觉得你不专业。
因此,我们要规定 commit 的提交频率。那到底什么时候进行 commit 最好呢?
- 进行了修改,一通过测试就立即 commit:比如修复完一个 bug、开发完一个小功能,或者开发完一个完整的功能,测试通过后就提交
- 我们规定一个时间,定期提交:这里我建议代码下班前固定提交一次,并且要确保本地未提交的代码,延期不超过 1 天。这样,如果本地代码丢失,可以尽可能减少丢失的代码量。
commit 太多怎么办
如果想等开发完一个完整的功能之后,放在一个 commit 中一起提交。这时候,我们可以在最后合并代码或者提交 Pull Request 前,执行 git rebase -i 合并之前的所有 commit。
合并提交
就是将多个 commit 合并为一个 commit 提交。
合并到主干时,使用 git rebase 命令来合并,只保留 2~3 个 commit 记录。
git rebase 命令介绍
git rebase 的最大作用是它可以重写历史。
我们通常会通过 git rebase -i 使用 git rebase 命令,-i 参数表示交互(interactive),该命令会进入到一个交互界面中,其实就是编辑器。在该界面中,我们可以对里面的 commit 做一些操作,交互界面如图所示:

这个交互界面会首先列出给定Commit ID之前(不包括,越下面越新)的所有 commit,每个 commit 前面有一个操作命令,默认是 pick。
可以选择不同的 commit,并修改 commit 前面的命令,来对该 commit 执行不同的变更操作。
