Git commit 消息的格式

在开发人员的日常工作中,提交代码到 Git 是必不可少的动作。代码提交时的消息该怎么写呢?最基本的原则是:如果团队有 commit 格式要求,就遵循该要求。这一点与代码风格是一样的。commit 消息的格式没有绝对的好与坏,最重要的是保持一致性。

如果团队没有具体的格式要求,可以参考下面的一些建议。

消息应该分成主题和内容两个部分,两部分用一个空行分隔。主题部分对 commit 的内容进行简要说明,不宜过长;内容部分应该具体描述所做的修改,以及进行修改的原因。

关于提交消息的格式,有一个比较流行的规范,称为约定式提交。约定式提交对提交信息做了一些约定,方便自动化工具进行处理。

约定式提交使用下面的格式:

<类型>[可选 范围]: <描述>

[可选 正文]

[可选 脚注]

约定式提交由 3 个部分组成,分别是类型和描述正文脚注,其中正文和脚注是可选的。

第一个部分是类型和描述。类型是 commit 的分类。常用的类型有如下几种:

  • fix 表示 bug 修复。
  • feat 表示新增功能。
  • build 表示构建相关。
  • chore 表示重复性的日常任务,比如更新依赖的版本。
  • ci 表示持续集成相关。
  • docs 表示文档相关。
  • style 表示代码格式相关。
  • refactor 表示代码重构。
  • perf 表示性能相关。
  • test 表示测试相关。

类型之后可以添加可选的范围,放在括号里面,表示 commit 对应的组件。比如,fix(api) 表示对 API 组件的 bug 修复。

消息的第二个部分是可选的正文,可以使用空格分隔多个段落。

消息的第三个部分是可选的脚注。脚注采用 git trailer format,是一个简单的名值对的形式。

下面给出了一个 commit 消息的示例,来自 Angular 的 GitHub 仓库。

feat(docs-infra): add @developerPreview tag for APIs in developer p…
…review (#46050)

This commit adds a tag processor for `@developerPreview`. Adding this tag to
an exported symbol or to a decorator parameter causes an API status tag to
be shown for the API which links to the Developer Preview documentation.

PR Close #46050

约定式提交对破坏性变更有特殊的处理。如果 commit 的改动包含了破坏性的变更,有两种方式来表示:

  • 第一种方式是在类型和范围之后添加感叹号,如 feat(api)!
  • 第二种方式是在脚注中添加 BREAKING CHANGE,如 BREAKING CHANGE: some changes

下面给出了一个使用 BREAKING CHANGEcommit 示例。

fix(router): Remove deprecated initialNavigation option (#45729)
BREAKING CHANGE:
`initialNavigation: 'enabled'` was deprecated in v11 and is replaced by
`initialNavigation: 'enabledBlocking'`.

PR Close #45729

如果想要看看格式完整的 commit 是什么样的,可以参考 Linux 和 Git 的源代码仓库,比如下面的 commit 来自 Git。

sha1-file.c: don't freshen cruft packs
We don't bother to freshen objects stored in a cruft pack individually
by updating the `.mtimes` file. This is because we can't portably `mmap`
and write into the middle of a file (i.e., to update the mtime of just
one object). Instead, we would have to rewrite the entire `.mtimes` file
which may incur some wasted effort especially if there a lot of cruft
objects and they are freshened infrequently.

Instead, force the freshening code to avoid an optimizing write by
writing out the object loose and letting it pick up a current mtime.

This works because we prefer the mtime of the loose copy of an object
when both a loose and packed one exist (whether or not the packed copy
comes from a cruft pack or not).

This could certainly do with a test and/or be included earlier in this
series/PR, but I want to wait until after I have a chance to clean up
the overly-repetitive nature of the cruft pack tests in general.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
版权所有 © 2024 灵动代码