Git Commit Message规范
<h3>版本记录</h3>
<table>
<thead>
<tr>
<th>版本号</th>
<th>版本说明</th>
<th>作者</th>
<th>日期</th>
<th>备注</th>
</tr>
</thead>
<tbody>
<tr>
<td>V1.0</td>
<td>Git Commit Message规范</td>
<td>Meeler</td>
<td>2018-08-22</td>
<td>修订版</td>
</tr>
<tr>
<td>------------</td>
<td>------------</td>
<td>------------</td>
<td>------------</td>
<td>------------</td>
</tr>
</tbody>
</table>
<hr />
<p>对每一个代码库的开发者而言,与未来的代码维护者(很多时间可能还是自己)之间进行沟通的最好方式无疑是一段精心设计的git commit信息。diff结果的确能告诉你哪些地方变动过,但是,只有commit消息才能让你明白为什么要做这些改动。</p>
<blockquote>
<p>通过代码改动本身来还原上下文、推测改动原因的做法绝对是一种浪费,但往往我们无法完全杜绝,我们需要做的是尽可能的避免。commit消息就是达成该目的的一种有效的方式。此外,通过commit消息也能看出一个开发者的自我修养。</p>
</blockquote>
<h2>Commit message 的作用</h2>
<ul>
<li>
<p>提供更多的历史信息,方便快速浏览 <code>git log <last tag> HEAD --pretty=format:%s</code></p>
<blockquote>
<p>上述命令显示上次发布后的变动,每个commit占据一行。只看行首,就能知道某次 commit 的目的。</p>
</blockquote>
</li>
<li>
<p>过滤某些commit内容,快速查找信息 <code>git log <last release> HEAD --grep feature</code></p>
<blockquote>
<p>上述命令显示本次发布新增加的功能</p>
</blockquote>
</li>
<li>直接从commit生成Change log
<blockquote>
<p>Change Log 是发布新版本时,用来说明与上一个版本差异的文档</p>
</blockquote></li>
</ul>
<h2>Commit message 的格式</h2>
<p><a href="https://git-scm.com/docs/git-commit" title="git-commit语法">git-commit语法链接</a></p>
<p>commit message 应该清晰明了,说明本次提交的目的。</p>
<h4>Commit message 的格式</h4>
<p>命令行: git commit -m "hello world"</p>
<pre><code><type>(<scope>): <subject>
// 空一行
<body>
// 空一行
<footer>
# 标题行:50个字符以内,描述主要变更内容
#
# 主体内容:更详细的说明文本,建议72个字符以内。 需要描述的信息包括:
#
# * 为什么这个变更是必须的? 它可能是用来修复一个bug,增加一个feature,提升性能、可靠性、稳定性等等
# * 他如何解决这个问题? 具体描述解决问题的步骤
# * 是否存在副作用、风险?
#
# 尾部:如果需要的化可以添加一个链接到issue地址或者其它文档,或者关闭某个issue。</code></pre>
<ol>
<li>每次提交,Commit message 都包括三个部分:Header,Body 和 Footer。Header 是必需的,Body 和 Footer 可以省略。</li>
<li>不管是哪一个部分,任何一行都不得超过72个字符(或100个字符)。这是为了避免自动换行影响美观。</li>
</ol>
<h4>Header</h4>
<blockquote>
<ul>
<li><strong>type</strong>
用于说明 commit 的类别,只允许使用下面7个标识:
<pre><code>feat:新功能(feature)
fix:修补bug
docs:文档(documentation)
style: 格式(不影响代码运行的变动)
refactor:重构(即不是新增功能,也不是修改bug的代码变动)
test:增加测试
chore:构建过程或辅助工具的变动</code></pre></li>
<li><strong>scope</strong>
用于说明 commit 影响的范围,比如数据层、控制层、视图层等等,视项目不同而不同。</li>
<li><strong>subject</strong>
subject是 commit 目的的简短描述,不超过50个字符;以动词开头,使用第一人称现在时,比如change,而不是changed或changes;第一个字母小写,结尾不加句号</li>
</ul>
</blockquote>
<ul>
<li>前缀标记: <font color="blue"><strong>[BUGFIX]</strong> / <strong>[FEATURE]</strong> / <strong>[CLEANUP]</strong> / <strong>[WIP]</strong></font></li>
<li>尽可能让整行内容长度限制在<strong>52</strong>个字符以内,无论如何不超过<strong>80</strong>
<div style="background-color:pink;padding:10px">前缀标记适用场景:
<font color="blue">**[BUGFIX]**</font>: 修复某个bug
<font color="blue">**[FEATURE]**</font>: 新增feature。新的feature主要针对*master*分支,其他旧分支不允许存在新feature,如有例外,需讨论并谨慎处理。
<font color="blue">**[CLEANUP]**</font>: 不涉及代码功能性修改,仅用于改进代码样式、提高代码可读性或组件优化
<font color="blue">**[WIP]**</font>: 还在进行中的工作。一旦最终版本完成时则会移除该标记,<font color="red">**所有被标记为WIP的改动不得进行分支合并**</font>
</div></li>
</ul>
<h4>Body</h4>
<ul>
<li>对修复的问题或代码的改动进行必要说明</li>
<li>说明尽可能的简要,重点在于解释代码改动的原因。无需重复原Issue tracker中已有的信息,也不需对代码改动内容本身进行说明</li>
<li>每行长度建议不超过<strong>72</strong>个字符</li>
<li>尽量使用祈使语气(e.g. Fix bug而不是Fixed bug),因为commit消息主要还是通过一系列改动涉及的指令、动作来描述如何从以前的状态变更为当前状态的过程。这一点也是为了跟默认的git merge或git revert命令的自动生成的消息保持一致。</li>
</ul>
<pre><code>- 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.</code></pre>
<h4>Footer</h4>
<p>适用于如下两种情形:</p>
<ul>
<li>
<p>不兼容变动</p>
<blockquote>
<p>如果当前代码与上一个版本不兼容,则 Footer 部分以BREAKING CHANGE开头,后面是对变动的描述、以及变动理由和迁移方法。</p>
<pre><code>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.</code></pre>
</blockquote>
</li>
<li>关闭 Issue
<blockquote>
<p>如果当前 commit 针对某个issue,可以在 footer 部分关闭这个 issue ,也可以关闭多个issue。</p>
<pre><code>Closes #234</code></pre>
</blockquote></li>
</ul>
<h4>Revert</h4>
<p>一种特殊情况,如果当前 commit 用于撤销以前的 commit,则必须以revert:开头,后面跟着被撤销 Commit 的 Header。</p>
<pre><code>revert: feat(pencil): add 'graphiteWidth' option
This reverts commit 667ecc1654a317a13331b17617d973392f415f02.</code></pre>
<ol>
<li>Body部分的格式是固定的,必须写成This reverts commit <hash>.,其中的hash是被撤销 commit 的 SHA 标识符。</li>
<li>如果当前 commit 与被撤销的 commit,在同一个发布(release)里面,那么它们都不会出现在 Change log 里面。如果两者在不同的发布,那么当前 commit,会出现在 Change log 的Reverts小标题下面。</li>
</ol>
<h2>Commit message 示例</h2>
<ul>
<li>
<p>bug修改提交</p>
<blockquote>
<p>[BUGFIX] fix bug
Fix homePage style bug.</p>
</blockquote>
</li>
<li>
<p>新增内容提交到master分支</p>
<blockquote>
<p>[FEATURE]
Add ignore settings.</p>
</blockquote>
</li>
<li>
<p>代码样式改进或组件优化</p>
<blockquote>
<p>[CLEANUP]
首页按钮样式变更,由蓝色变为紫色。</p>
</blockquote>
</li>
<li>临时提交
<blockquote>
<p>[WIP]
登录功能完成。</p>
</blockquote></li>
</ul>
<hr />