【译】Git Commit Message 格式约定

1,074 阅读1分钟

原文链接

目的

  1. 可以自动生成 CHANGELOG;
  2. 可以忽略通过git bisect生成的commit message;
  3. 为浏览提交历史提供更清晰的格式;

生成 CHANGELOG

在更改日志中使用这三个部分:新功能bug修复非后向兼容变更(breaking change)

在发布版本时,这三个部分的内容可由脚本生成,并指向相关commit的链接。

当然,也可以在实际发布之前基于脚本生成骨架,手动编辑CHANGELOG的内容。

查看自上次发布以来所有提交主题(提交消息中的第一行)的列表:

git log <last tag> HEAD --pretty=format:%s

查看当前版本中的新功能:

git log <last release> HEAD --grep feature

识别不重要的提交

一些格式更改(添加/删除空格/空行、缩进)、缺少分号、注释。因此,当查看代码变更内容时,可以忽略这些提交,因为这些提交中没有实际业务逻辑的变动。

在一起时,您可以忽略这些:

git bisect skip $(git rev-list --grep irrelevant <good place> HEAD)

为浏览提交历史提供更清晰的格式

这将添加一些 "上下文" 信息。

看看下面这些这些commit message 示例(来自Angular项目):

  • Fix small typo in docs widget (tutorial instructions)
  • Fix test for scenario.Application - should remove old iframe
  • docs - various doc fixes
  • docs - stripping extra new lines
  • Replaced double line break with single when text is fetched from Google
  • Added support for properties in documentation

上面这些消息都尝试指定更改的范围,但它们没有遵循任何约定。

再看看以下消息:

  • fix comment stripping
  • fixing broken links
  • Bit of refactoring
  • Check whether links do exist and throw exception
  • Fix sitemap include (to work on case sensitive linux)

你能明白这些信息说明了什么吗?它们没有指明修改的范围。

因此,也许像代码的一部分:docs, docs-parser, compiler, scenario-runner,...

当然,可以通过检查哪些文件被更改来找到此信息,但是效率很低。在查看git历史记录时,我可以看到我们都试图在message中指定修改范围,但只是缺少了约定。

提交消息的格式

<type>(<scope>): <subject>

<BLANK LINE>

<body>

<BLANK LINE>

<footer>

提交消息的任何行不能超过 100个字符!这允许消息更容易在 github 以及各种 git 工具中阅读。

提交消息由标头(第一行)、bodyfooter组成,用空白行分隔。

Revert 如果是还原以前的提交,则其标头应以"revert:"开始,后面跟着要还原提交的标题。在正文中,可以参考如下格式:"This revert commit <hash>",其中哈希是正在还原的提交SHA。

消息标题
提交消息头一行称为标题,其中包含type(类型)、scope(可选 变更范围)和这次更改的简洁描述。

Allowed <type>

用type字段描述这次变更的主要类型。

  • feat (feature)
  • fix (bug fix)
  • docs (documentation)
  • style (formatting, missing semi colons, …)
  • refactor
  • test (when adding missing tests)
  • chore (maintain)

<scope>

范围可以是指定提交更改位置的任何东西。例如,locationlocation,browser,compilecompile,rootScope、ngHref、ngClick、ngView 等...

如果没有更合适的范围,可以使用*

<subject>文本

对这次提交的简洁描述

  • 使用现在时态的命令: “change” not “changed” nor “changes”
  • 不大写第一个字母
  • 末尾没有点.

消息正文

  • 就像 <subject> 使用的命令, 当前时态: “change” not “changed” nor “changes”
  • 包括更改的目的和与以前行为的对比

writing-git-commit-messages a-note-about-git-commit-messages

消息页脚

重大更改

所有的非后向兼容更改必须作为页脚中的单独区域来提及,该更改应以"breaking change:" 一词开始。然后,提交消息的其余部分是更改、对齐和迁移注释的说明。

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',
      myBind: 'bind',
      myExpression: 'expression',
      myEval: 'evaluate',
      myAccessor: 'accessor'
    }

    After:

    scope: {
      myAttr: '@',
      myBind: '@',
      myExpression: '&',
      // myEval - usually not useful, but in cases where the expression is assignable, you can use '='
      myAccessor: '=' // in directive's template change myAccessor() to myAccessor
    }

    The removed `inject` wasn't generaly useful for directives so there should be no code using it.

Referencing issues

关闭bug类的提交应该单独列出被关闭的bug号并且以"Closes"开头

Closes #234

或者多个bug的情况

Closes #123, #245, #992

Examples

feat($browser): onUrlChange event (popstate/hashchange/polling)

Added new event to $browser:
- forward popstate event if available
- forward hashchange event if popstate not available
- do polling when neither popstate nor hashchange available

Breaks $browser.onHashChange, which was removed (use onUrlChange instead)

fix($compile): couple of unit tests for IE9

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

feat(directive): ng:disabled, ng:checked, ng:multiple, ng:readonly, ng:selected

New directives for proper binding these attributes in older browsers (IE).
Added coresponding description, live examples and e2e tests.

Closes #351

style($location): add couple of missing semi colons

docs(guide): updated fixed docs from Google Docs

Couple of typos fixed:
- indentation
- batchLogbatchLog -> batchLog
- start periodic checking
- missing brace

feat($compile): simplify isolate scope bindings

Changed the isolate scope binding options to:
  - @attr - attribute binding (including interpolation)
  - =model - by-directional model binding
  - &expr - expression execution binding

This change simplifies the terminology as well as
number of choices available to the developer. It
also supports local name aliasing from the parent.


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',
  myBind: 'bind',
  myExpression: 'expression',
  myEval: 'evaluate',
  myAccessor: 'accessor'
}

After:

scope: {

  myAttr: '@',
  myBind: '@',
  myExpression: '&',
  // myEval - usually not useful, but in cases where the expression is assignable, you can use '='
  myAccessor: '=' // in directive's template change myAccessor() to myAccessor
}

The removed `inject` wasn't generaly useful for directives so there should be no code using it.