Commit 规范(一)
项目开发时,一个好的 Commit Message 至关重要:
- 可以使自己或者其他开发人员能够清晰地知道每个 commit 的变更内容,方便快速浏览变更历史,比如可以直接略过文档类型或者格式化类型的代码变更。
- 可以基于这些 Commit Message 进行过滤查找,比如只查找某个版本新增的功能:
git log --oneline --grep "^feat|^fix|^perf"
。 - 可以基于规范化的 Commit Message 生成 Change Log。
- 可以依据某些类型的 Commit Message 触发构建或者发布流程,比如当 type 类型为 feat、fix 时我们才触发 CI 流程。
- 确定语义化版本的版本号。比如
fix
类型可以映射为 PATCH 版本,feat
类型可以映射为 MINOR 版本。带有BREAKING CHANGE
的 commit,可以映射为 MAJOR 版本。
Commit Message 的规范
有以下几种:
在这些规范中,Angular 规范在功能上能够满足开发者 commit 需求,在格式上清晰易读,目前也是用得最多的。
Angular 规范其实是一种语义化的提交规范(Semantic Commit Messages),所谓语义化的提交规范包含以下内容:
- Commit Message 是语义化的:Commit Message 都会被归为一个有意义的类型,用来说明本次 commit 的类型。
- Commit Message 是规范化的:Commit Message 遵循预先定义好的规范,比如 Commit Message 格式固定、都属于某个类型,这些规范不仅可被开发者识别也可以被工具识别。
一个遵循 Angular 规范的 commit 历史记录:
一个完整的符合 Angular 规范的 Commit Message:
Angular 规范
在 Angular 规范中,Commit Message 包含三个部分,分别是 Header、Body 和 Footer,格式如下:
<type>[optional scope]: <description>
// 空行
[optional body]
// 空行
[optional footer(s)]
其中,Header是必需的,Body和Footer可以省略。在以上规范中,必须用括号 ()
括起来, <type>[<scope>]
后必须紧跟冒号 ,冒号后必须紧跟空格,2 个空行也是必需的。
在实际开发中,为了使 Commit Message 在 GitHub 或者其他 Git 工具上更加易读,往往会限制每行 message 的长度。根据需要,可以限制为 50/72/100 个字符。
以下是一个符合 Angular 规范的 Commit Message:
fix($compile): couple of unit tests for IE9
# Please enter the Commit Message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
# ...
Older IEs serialize html uppercased, but IE9 does not...
Would be better to expect case insensitive, unfortunately jasmine does
not allow to user regexps for throw expectations.
Closes #392
Breaks foo.bar api, foo.baz should be used instead
Angular 规范中 Commit Message 的三个部分:
Header
Header 部分只有一行,包括三个字段:type(必选)、scope(可选)和 subject(必选)。
type
分为两个类别:
- Development:这类修改一般是项目管理类的变更,不会影响最终用户和生产环境的代码,比如 CI 流程、构建方式等的修改。遇到这类修改,通常也意味着可以免测发布。
- Production:这类修改会影响最终的用户和生产环境的代码。所以对于这种改动,一定要慎重,并在提交前做好充分的测试。
常见 type 和它们所属的类别:
如何确定一个 commit 所属的 type:
scope
用来说明 commit 的影响范围。显然,不同项目会有不同的 scope。在项目初期,可以设置一些粒度比较大的 scope,比如可以按组件名或者功能来设置 scope;后续,如果项目有变动或者有新功能,可以再用追加的方式添加新的 scope。
scope 不适合设置太具体的值。太具体的话,一方面会导致项目有太多的 scope,难以维护。另一方面,开发者也难以确定 commit 属于哪个具体的 scope,导致错放 scope,反而会使 scope 失去了分类的意义。
subject
subject 是 commit 的简短描述,必须以动词开头、使用现在时。比如,可以用 change,却不能用 changed 或 changes,而且这个动词的第一个字母必须是小写。通过这个动词,可以明确地知道 commit 所执行的操作。此外还要注意,subject 的结尾不能加英文句号。
Body
Body 部分可以分成多行,而且格式也比较自由。不过,和 Header 里的一样,它也要以动词开头,使用现在时。此外,它还必须要包括修改的动机,以及和跟上一版本相比的改动点。
Footer
Footer 部分不是必选的,可以根据需要来选择,主要用来说明本次 commit 导致的后果。在实际应用中,Footer 通常用来说明不兼容的改动和关闭的 Issue 列表,格式如下:
BREAKING CHANGE: <breaking change summary>
// 空行
<breaking change description + migration instructions>
// 空行
// 空行
Fixes #<issue number>
-
不兼容的改动:如果当前代码跟上一个版本不兼容,需要在 Footer 部分,以
BREAKING CHANG:
开头,后面跟上不兼容改动的摘要。Footer 的其他部分需要说明变动的描述、变动的理由和迁移方法BREAKING CHANGE: isolate scope bindings definition has changed and the inject option for the directive controller injection was removed. 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.
-
关闭的 Issue 列表:关闭的 Bug 需要在 Footer 部分新建一行,并以 Closes 开头列出,例如:
Closes #123
。如果关闭了多个 Issue,可以这样列出:Closes #123, #432, #886
。例如:Change pause version value to a constant for image Closes #1137
Revert Commit
如果当前 commit 还原了先前的 commit,则应以 revert:
开头,后跟还原的 commit 的 Header。而且,在 Body 中必须写成 This reverts commit <hash>
,其中 hash 是要还原的 commit 的 SHA 标识。例如:
revert: feat(iam-apiserver): add 'Host' option
This reverts commit 079360c7cfc830ea8a6e13f4c8b8114febc9b48a.
总结
为了更好地遵循 Angular 规范,建议在提交代码时养成不用 git commit -m
,即不用-m 选项的习惯,而是直接用 git commit
或者 git commit -a
进入交互界面编辑 Commit Message。这样可以更好地格式化 Commit Message。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验