Git Commit Message 约定
AngularJS Git Commit Message Conventions
目的
- 通过脚本生成 CHANGELOG.md
- 允许通过 git bisect 忽略 commits (不重要的 commit,如调整格式造成的 commit)
- 在提交历史中,提供更多有价值信息
生成 CHANGELOG.md
在 changelog 中,有三个段落: *** 新功能(new features), *** 修改 bug(bug fixes), 重大更改(breaking changes).
在发布版本的时候,我们可以通过脚本,根据有关 commit 来生成以上段落的列表。
当然,脚本可以生成纲要,而我们可以在实际发布前编辑 changelog,。
列出自上次版本发布后,所有的主题(commit message 的第一行):
>> git log <last tag> HEAD --pretty=format:%s
列出这次版本发布中,所有的新功能(New features)
>> git log <last release> HEAD --grep feature
鉴别重要/不重要的 commits
不重要的 commit,如格式变化(增删空格、增删空行、增删缩进)、修改缺少的冒号、提交注释。当我们只想看有意义的代码变化的时候,我们可以忽略这些 commit -- 这些 commit 中没有代码逻辑上的变化。
在区分的时候,我们可以这样:
>> git bisect skip $(git rev-list --grep irrelevant <good place> HEAD)
在提交历史中,提供更多有价值信息
commit message 可以增添一点“内容”信息。
如下例:
- Fix small typo in docs widget (tutorial instructions)(修正文档组件中,一些轻微的排版错误。教程说明中)
- Fix test for scenario.Application - should remove old iframe(修正 scenario.Application 的测试 - 应该移除旧的 iframe)
- docs - various doc fixes (文档 - 各种文档修正)
- docs - stripping extra new lines(文档 - 剥离额外的空行)
- Replaced double line break with single when text is fetched from Google(将从 Google 获取的文本中,双换行符替换成单换行符)
- Added support for properties in documentation(增加对文本属性的支持)
所有这些信息,尝试指出哪里变化了,即使他们的约定格式并不同。
再看下例:
- fix comment stripping(修正注释)
- fixing broken links(修正失效的链接)
- Bit of refactoring(重构 bit 位)
- Check whether links do exist and throw exception(检查链接是否存在,并抛出异常)
- Fix sitemap include (to work on case sensitive linux)(修正网站地图成员,针对大小写敏感的 linux)
我们猜不出这些改变的具体位置,这些消息缺少对具体位置的说明...
如果按照位置划分 changelog 段落,或许应该有段落: docs, docs-parser, compiler, scenario-runner, …
这样虽然能够更好的对变化的代码进行分类,但是这样做比较繁琐,因而我们不采用.
commit message 的格式
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
commit message 一行的宽度不能超过 100 个字符(双字节 50 个汉字),遵守这个要求能够让信息在 github 上更容易的被阅读。
一条 commit message 包括头、体、尾三部分,三部分之间用一个空行分割。
还原(Revert)
如果一条 commit 还原了较早的另一条 commit,它的 message 头,应该以 revert:
开头。接着写被还原的 commit 的 message 头。在 message 体中,应写: 还原 commit <hash>.
,<hash>
中填写被还原 commit 的 SHA 字符串。
信息头
Message 头是一行用来描述代码变化的简洁的描述,包括代码变化的类型
、主题
,还可以酌情加上范围
。
合法的 <type>
以下列表是合法代码变化的 <type>
- feat (feature)
- fix (bug fix)
- docs (documentation)
- style (formatting, missing semi colons, …)
- refactor
- test (when adding missing tests)
- chore (maintain)
合法的 <scope>
范围
可以是发生代码的任何地方。
<subject> text
对代码变化尽量简洁、尽量短的描述。
- use imperative, present tense: “change” not “changed” nor “changes”
- don't capitalize first letter
- 不要在结尾加句号。
信息体
对代码变化尽量简洁、尽量短的描述。
要包括作出代码修改的动机、目的,新的目的同过去目的的比较。
http://365git.tumblr.com/post/3308646748/writing-git-commit-messages
http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
信息尾
重大更新(Breaking changes)
所有重大更新,必须在消息尾中被说明,说明以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.
引用 issues
Closed bugs should be listed on a separate line in the footer prefixed with "Closes" keyword like this:
Closes #234
or in case of multiple issues:
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.