Yves

Git之正确的commit姿势

参考

一.commit信息怎么写

首先贴一张图看看别人家的commit是长什么样的

大家也可以去github上看看国际知名项目的Commit信息,比如okhttp,至少是对自己做了什么描述得很清楚.

再来看一下坏栗子:

1
2
git commit -m "Fix a bug"
# --What the hell! 鬼知道你fix的是个什么bug啊.

Git 每次提交代码,都要写 Commit message(提交说明),否则就不允许提交,像这样:

1
$ git commit -m '这是一次不太规范的提交'

如果一行不够,可以只执行git commit,就会跳出文本编译器,让你写多行。AS上图形界面点击commit弹出来的那个窗口就带有了编辑器,直接在那里编辑commit信息也行.

那么,写些什么很关键.无论如何,github上的dalao们的commit信息逼格就比我们的高很多.

一般来说,commit message 应该清晰明了,说明本次提交的目的。

再贴一张图:

目前社区上有多种commit message的规范,但使用最广的写法,是Angular规范

Commit Message 格式

1
2
3
4
5
<type>(<scope>): <subject>
<空行>
<body>
<空行>
<footer>

这是一次Commit后Message格式规范,分成标题(Header),内容详情(body),结尾(Footer) 三个部分,各有各的用处,没有多余项。

其中,Header 是必需的,Body 和 Footer 可以省略。

不管是哪一个部分,任何一行都不得超过72个字符(或100个字符)。这是为了避免自动换行影响美观。

  • Header
    头部即首行,是可以直接在页面中预览的部分,入上面图中所示,一共有三个部分<type>,<scope>,<subject>

    • Type
      • feat:新功能(feature)
      • fix:修补bug
      • docs:文档(documentation)
      • style: 格式(不影响代码运行的变动)
      • refactor:重构(即不是新增功能,也不是修改bug的代码变动)
      • test:增加测试
      • chore:构建过程或辅助工具的变动
    • Scope
      用来说明本次Commit影响的范围,即简要说明修改会涉及的部分,比如数据层、控制层、视图层等等,视项目不同而不同
    • Subject
      用来简要描述本次改动,概述就好了,因为后面还会在Body里给出具体信息。并且最好遵循下面三条:
      • 以动词开头,使用第一人称现在时,比如change,而不是changed或changes
      • 首字母不要大写
      • 结尾不用句号(.)
  • Body
    <body>里的内容是对上面subject里内容的展开,在此做更加详尽的描述,内容里应该包含修改动机和修改前后的对比。看一个示例

    1
    2
    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
    • 使用第一人称现在时,比如使用change而不是changed或changes。
    • 应该说明代码变动的动机,以及与以前行为的对比。
  • Footer
    footer里的主要放置不兼容变更和Issue关闭的信息

    • 不兼容变动
      如果当前代码与上一个版本不兼容,则 Footer 部分以BREAKING CHANGE开头,后面是对变动的描述、以及变动理由和迁移方法。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      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.
    • 关闭 Issue
      如果当前 commit 针对某个issue,那么可以在 Footer 部分关闭这个 issue

      1
      2
      3
      4
      //关闭一个issue
      Closes #234
      //关闭多个issue
      Closes #123, #245, #992
  • Revert

还有一种特殊情况,如果当前 commit 用于撤销以前的 commit,则必须以revert:开头,后面跟着被撤销 Commit 的 Header(SHA码)。

1
2
3
revert: feat(pencil): add 'graphiteWidth' option
This reverts commit 667ecc1654a317a13331b17617d973392f415f02.

Body部分的格式是固定的,必须写成This reverts commit <hash>.其中的hash是被撤销 commit 的 SHA 标识符。

commit message的规范就这些了,也不算多,推荐一个Terminal插件Commitiz(不知道在Windows上怎么用,如果直接在AS上Commit的话就永不上了,也可以搜搜看AS有没有相应插件)
安装命令

1
2
3
$ npm install -g commitizen
# 然后,在项目目录里,运行下面的命令,使其支持 Angular 的 Commit message 格式。
$ commitizen init cz-conventional-changelog --save --save-exact

以后,凡是用到git commit命令,一律改为使用git cz。这时,就会出现选项,用来生成符合格式的 Commit message。

最后还有值得注意的是commit粒度的问题

粒度是指修改的粒度.如果你做了很多修改,但是就只提交了一次,那么粒度就太大了.这样在commit信息中三言两语又讲不清楚做了什么修改,详细说得话又变得长篇大论.
这就需要适度减小粒度.但是也不要做一点提交一点,比如写一行代码commit一次,这就导致commit信息太啰嗦,而且也不知道要写什么.

具体该什么时候提交,要看具体情况.比如要增加某个功能,如果这个功能非常简单,添加少部分代码就可以实现,那么整个功能完成之后再commit就OK,但是如果这个功能是个很庞大的工程,需要拆分成若干个小步骤完成,那么每个步骤小步骤完成之后就应该commit了.