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 CHANGE
的 commit 示例。
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>