← back

Git Commit 规范

基于Angular标准,具体的谈一下 git commit 中的规范和最佳实践

前言

不知道你是否会在每次commit的时候都纠结该如何描述,如果有的话,则说明你对git commit的标准不太了解,其实早已有人制定了一个比较规范的git commit标准,叫作 Angular规范 ,在阮一峰老师这篇:Commit message 和 Change log 编写指南 文章中比较详细的记录了相关的细节

但是阮一峰老师这篇文章中缺少对全流程的描述、工具的使用等细节,这对初学者来说会比较困惑,本文就解决这个部分的内容

Commit message 的格式

每次提交,Commit message 都包括三个部分:Header,Body 和 Footer

<type>(<scope>): <subject>
// 空一行
<body>
// 空一行
<footer>

其中,Header 是必需的,Body 和 Footer 可以省略

不管是哪一个部分,任何一行都不得超过72个字符(或100个字符)。这是为了避免自动换行影响美观

Header

Header部分只有一行,包括三个字段:type(必需)、scope(可选)和subject(必需)。

  1. **type:**用于说明 commit 的类别,只允许使用下面7个标识,最常用!!

    • feat:新功能(feature)
    • fix:修补bug
    • docs:文档(documentation)
    • style: 格式(不影响代码运行的变动)
    • refactor:重构(即不是新增功能,也不是修改bug的代码变动)
    • test:增加测试
    • chore:构建过程或辅助工具的变动

    如果typefeatfix,则该 commit 将肯定出现在 Change log 之中。其他情况(docschorestylerefactortest)由你决定,要不要放入 Change log,建议是不要

  2. scope:用于说明 commit 影响的范围,比如数据层、控制层、视图层等等,视项目不同而不同

  3. subject:commit 目的的简短描述,不超过50个字符

    • 以动词开头,使用第一人称现在时,比如change,而不是changedchanges
    • 第一个字母小写
    • 结尾不加句号(.

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

有两个注意点

Footer

Footer 部分只用于两种情况。

  1. 不兼容变动

    如果当前代码与上一个版本不兼容,则 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 #123, #245, #992

Revert

还有一种特殊情况,如果当前 commit 用于撤销以前的 commit,则必须以revert:开头,后面跟着被撤销 Commit 的 Header

revert: feat(pencil): add 'graphiteWidth' option

This reverts commit 667ecc1654a317a13331b17617d973392f415f02.

Body部分的格式是固定的,必须写成This reverts commit &lt;hash>.,其中的hash是被撤销 commit 的 SHA 标识符。

如果当前 commit 与被撤销的 commit,在同一个发布(release)里面,那么它们都不会出现在 Change log 里面。如果两者在不同的发布,那么当前 commit,会出现在 Change log 的Reverts小标题下面

1. 背景:Git Commit 规范的用途及其在 GitHub Flow 中的位置

以防你不知道 github flow 是什么,你可以先阅读关于github flow的介绍,简单来说在一个标准flow中,每一次的 git commit 的记录应该是清晰符合标准的,这样才方便协作

目前大多使用Angular这个规范,当然这只是一个规范或者说指导,并不是强制的执行标准,不过和其他规范一样,其意义是确保每次提交都具备清晰、规范、易读的描述,这不仅有助于团队协作,也方便后续代码回溯、问题定位和版本管理。良好的提交信息能够让代码仓库的历史更具可读性,减少沟通成本

在 GitHub Flow 中,commit 是开发流程中的关键阶段,通常发生在本地分支开发完成后,将代码推送到远程分支之前。具体位置包括:

通过统一 commit 规范,团队成员可以快速理解代码变更的内容和目的,从而提高协作效率和项目质量。


2. 补充:利用工具和 IDE 插件优雅书写和检查 Git Commit

补充阮一峰老师文章:现代编码都是基于IDE,且往往是图像界面操作,所以git commit 的规范化也可以结合IDE进行

编写规范的 commit 信息看似简单,但实际操作中往往会因为格式、内容不规范导致团队沟通障碍。为此,可以借助以下工具和插件提升体验:

合理使用工具可以大幅减少人工检查的成本,让 commit 编写过程更流畅、规范

下面是一个使用 Git Commit Plugin 的示例,其他的插件也差不多

image.png

image.png

image.png

image.png


3. 补充:如何优雅生成 CHANGELOG(不完全)

如果你注意观察的话,在一些开源软件中包含一个CHANGELOG文件或者是文件夹,里面描述了每次版本迭代所做出的改变,并且还包括此次更新所关闭的issus等,这是一种比较优雅的方式,但其实这部分的内容很多是基于自动化工具生成,然后再人工进行的校验,其中自动化生成的关键就是需要使用规范的commit标准

自动生成 CHANGELOG 可以提高效率,也保证日志的准确和一致性。常用的工具包括:

通过这些工具:

IDE 也有相关插件,结合上述工具可以实现一键生成和预览 CHANGELOG,提升用户体验。


4. Commit 关闭 Issue 的最佳实践及其优点

阮一峰老师提到的通过 commit message 关闭 Issue(例如使用 fix #123)是一种被广泛认可的实践,背后有以下优点:

最佳实践建议:

在github中支持PR模板的用法,创建一个 .github/pull_request_template.md

PR模板示例:

### ✨ What’s Changed

<!--
简要列出本次 PR 中的主要改动点。
推荐使用语义化 commit 风格(feat/fix/refactor/docs/test 等)。
例如:

- feat(login): add email format validation
- fix(auth): handle expired token
- refactor(session): extract common logic
-->

### 🐛 Related Issues

<!--
自动关闭 Issue 的语法:
Fixes #123
Closes #456
如果只是提到,不想自动关闭,用:
Related to #789
-->

Fixes #

### 📋 Additional Context

<!--
补充说明为什么做这些改动,有哪些考虑、上下文信息,是否是链式 PR 的一部分等。
例如:

This PR is the second step of the auth module refactor plan (after #101).
-->

5. 多个 Commit 进行 Squash 时的最佳操作指南

在合并 Pull Request 或整理历史时,通常会用 squash 把多个 commit 合并为一条,例如通过GitHub PR 合并时可直接选择 “Squash and merge” ,其他的平台一般也有类似的选项

这里会涉及到将多条 commit 合并为一条的需求,对于这个需求我没有找到统一的标准,我的个人习惯是使用上一条中的模板格式来进行commit的聚合,即PR内容分为三段表达

如果是在本地进行Squash,可以使用 git rebase -i 进行交互式合并

正确的 squash 习惯让代码库历史更清晰,方便后续维护和回滚


6. (可选)CI/CD 中的 Commit 自动化检查实践(不完全)

CI/CD 涉及到的内容会比较专业,不是短篇幅能说完的,一般在企业中往往会有专门的人进行维护,我对这个部分的内容也不是专业的,这里仅是泛泛而谈,后面等我彻底搞明白并摸索出最佳实践之后再补全

在现代开发流程中,CI/CD 流水线自动检测 commit 信息是否符合规范,是保证项目质量的关键环节。推荐做法:

这种全流程的自动化检查极大提升团队开发效率和代码质量,保障发布流程的可控性和规范性。