一个维护版本日志整洁的Git提交规范
本文由发表于4周前 | 工具类库 | 暂无评论 |  被围观 35 views+

1 关于提交日志规范

良好的Commit Message有利于代码审查,能更快速查找变更记录,并且可以直接生成Change log。

Commit Message的写法规范:conventional-changelog
为了规范代码提交的说明,这里我们使用angular的规范写法:

<type>(<scope>): <subject>
<空行>
<body>
<空行>
<footer>

其中 head((): )是必须的,body和footer是可选的。
如果只需要输入header,可以直接使用:

git commit -m

命令提交。

如果需要输入body、footer这样的多行日志,需要输入:

git commit

跳出文本编辑器进行编写。

1.1 Header

1.1.1 Type

commit的类别,包涵以下七种:

feat:新功能(feature)
fix:修补bug
docs:文档(documentation)
style: 格式(不影响代码运行的变动)
refactor:重构(即不是新增功能,也不是修改bug的代码变动)
test:增加测试
chore:构建过程或辅助工具的变动

1.1.2 Scope

commit的影响范围,比如会影响到哪个模块/性能/哪一层(业务层,持久层,缓存,rpc),如果是特性代码,可以写特性名称

1.1.3 Subject

commit的简短描述,不超过50个字符。

  • 使用现在式,祈使句
  • 第一个字母无需大写
  • 结尾不用加句号

1.2 Body

跟subject一样,使用现在式,祈使句。应该说明提交代码的动机,以及跟前一个版本的对比。

1.3 Footer

Foot包含可以包含以下信息:

1.3.1 描述重大变更的信息

以 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.

1.3.2 关闭JIRA

如:

Closes DB-1001, DB1002

1.4 一些 Commit Message 例子:

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

---------

eat(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

---------

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.

如果是特性开发,则可以这样:

feat(短视频播放优化): 全屏播放动画效果优化

2 提交日志自动校验

在NodeJS项目中,我们可以通过使用 ghooks + validate-commit-msg进行提交日志校验,校验不通过的将被拒绝提交。原理是通过NodeJs项目编译,把NodeJS的校验脚本写到.git/hooks/目录下的勾子文件中,这样每次执行git commit命令都会执行这个校验,不过这种方式依赖于Node环境,并且每个Git项目都需要引入对应的npm模块进行编译,对于比较多微服务项目的情况来说使用不太方便。

为此,编写了git-hook-maven-plugin插件, 该插件有如下特点:

  • 很方便的在项目中自定义团队的工作流, 把自定义钩子钩子脚本纳入git管理类, 方便团队共享;
  • 把钩子脚本的安装集成到Maven的生命周期中的某个阶段, 方便的通过项目编译自动安装或者升级脚本;
  • 提供通用的内置脚本, 方便钩子的配置, 目前只提供了validate-commit-message钩子脚本, 用于提交日志的规范, 遵循AngularJS Git Commit Message Conventions的格式。

具体安装参考说明文档

配置完这个,当我们通过maven编译完项目之后,下一次提交代码,如果提交日志不符合规范,则会报错:

➜  project-1 git:(master) ✗ git commit -m "test"

Commit log error: First commit message line (commit header) does not follow format: type(scope): subject
 - Refer commit guide: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#

3 特性开发提交压缩合并

对于独自完成的特性,可能在开发过程中会产生多个提交,为了让提交整洁,需要对这个特性的所有提交进行压缩合并。我们先看看压缩合并之前的代码:

* be6e32d (HEAD->master)feat(测试提交): 修改第二个文件
* 4a7615e feat(测试提交): 修改第一个文件
* 721064e feat(测试提交): 提交第四个文件
* e20968e feat(测试提交): 提交第三个文件
* b7160b3 feat(测试提交): 提交第二个文件
* 0c90fcl feat(测试提交): 提交第一个文件
* e618321 fix(页面展示): 展示错误修复

如图,可以发现压缩合并测试特性有多个提交,可以进行合并,现在准备把e618321前面的提交都进行合并,执行git rebase -i命令进行压缩合并:

git rebase -i e618321

其中命令后面的hash值是压缩合并开始的那个提交的hash值:

pick 0c90fcl feat (测试提交): 提交第一个文件
pick b7160b3 feat(测试提交): 提交第二个文件
pick e20968e feat(测试提交): 提交第三个文件
pick 721064e feat(测试提交): 提交第四个文件
pick 4a7615e feat(测试提交): 修改第一个文件
pick be6e32d feat(测试提交): 修改第二个文件

# Rebase e618321..be6e32d onto e618321 (6 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

注意:这个界面里面的提交是按照提交时间顺序往下排的,最新提交的在最后面,跟git lg的相反,平时查看日志是最新提交的排在最前面。

我们把低2行到6行改为 s(squash),第一个行改为 r(reword),把第2到6行合并到第一个提交里面,调整下提交信息:

r 0c90fcl feat (测试提交): 提交第一个文件
s b7160b3 feat(测试提交): 提交第二个文件
s e20968e feat(测试提交): 提交第三个文件
s 721064e feat(测试提交): 提交第四个文件
s 4a7615e feat(测试提交): 修改第一个文件
s be6e32d feat(测试提交): 修改第二个文件

然后输 :wq 保存并退出编辑模式继续处理。

如果遇到有冲突,需要解决完冲突之后,修改冲突的提交日志。

最后是一个压缩合并之后的提交日志确认界面,看看第一行的日志是否符合我们的需求,没有问题则输入 :wq 保存并退出编辑模式。

# This is acombination of 7commits.
# The first commit'smessage is:
feat(测试提交): 测试代码

# This is the 2nd commit message:

feat(测试提交): 提交第二个文件

# This is the 3rd commit message:

feat(测试提交): 提交第三个文件

这样我们就合并完成了,再次查看提交日志,发现已经合并程了一个提交:

* eb0121a (HEAD->master) feat(测试提交): 测试代码
* e618321 fix(页面展示): 展示错误修复

注:git lg中 lg = log --graph --oneline --decorate,特别注意,本次演示代码直接在master上面进行,实际上需要在 feature-xxx 分支上面进行。

提交代码和压缩合并的原则:

开发过程中的提交代码原则:
尽量减少commit的次数;
在push之前,需要把本次特性所有的代码都压缩成一个提交;
在提交代码审查之前,最好把本次特产压缩成一个提交

4 合并master代码使用 rebase

假设我们开发一个新的特性,并且已经把代码进行了压缩合并,提交日志如下:

* 69b4ffb (HEAD -> feature-test) feat(测试特性): 测试特性代码
* eb0121a (HEAD->master) feat(测试提交): 测试代码
* e618321 fix(页面展示): 展示错误修复

而此时,master代码也有了新的修复代码提交:

* 69b4ffb (HEAD -> master) fix(缓存): 修复产品接口缓存bug
* eb0121a (HEAD->master) feat(测试提交): 测试代码
* e618321 fix(页面展示): 展示错误修复

为了保持合并之后,我们当前特性点仍然在提交日志的最新位置,达成效果如下:

我们使用rebase进行合并代码:

git rebase master

合并之后效果如下,我们当前特性分支的提交仍然在最前面:

* 69b4ffb (HEAD -> feature-test) feat(测试特性): 测试特性代码
* 69b4ffb (HEAD -> master) fix(缓存): 修复产品接口缓存bug
* eb0121a (HEAD->master) feat(测试提交): 测试代码
* e618321 fix(页面展示): 展示错误修复

rebase代码原则:

特性分支合并master代码使用 rebase,总让当前特性处于最近提交;
如果一个特性有多个同事开发,rebase之前记得让其他同事提交所有代码,rebase之后记得让其他同事强制更新本地代码;

References

Git 提交的正确姿势:Commit message 编写指南
你可能会忽略的 Git 提交规范
Git钩子:自定义你的工作流
用 Node.js 写前端自己的 Git-hooks
https://gist.github.com/jasonrobertfox/8057124

Bash in Linux v.s Mac OS

GitUntrackedFilesMojo

除了文章中有特别说明,均为IT宅原创文章,转载请以链接形式注明出处。
本文链接:http://www.itzhai.com/a-git-submission-specification-that-maintains-a-clean-version-log.html
arthinking 指弹吉他 && 技术 more
分享到:
 
2018 7/27
文章评论
    没有评论
给我留言

有人回复时邮件通知我
工具类库的相关文章
随机文章 本月热门 热评
1 EXT的核心组件,相关的处理事件和类的使用 2011/7/24
2 Java动态代理之JDK动态代理和CGLib动态代理 面向切面编程AOP原理 2014/4/1
3 Python语法笔记4 2014/3/13
4 转角处的音乐梦想家 2012/7/4
5 进程管理相关内容-信号量 临界资源 PV操作 2011/6/29
6 C++语法笔记 – Windows程序设计介绍与MFC库 2011/9/3
友情推荐 更多
破博客 文官洗碗安天下,武将打怪定乾坤。多么美好的年代,思之令人泪落。
行知-追寻技术之美 关注大数据,分布式系统
我爱编程 编程成长轨迹
Cynthia's Blog 学习笔记 知识总结 思考感悟
 
欢迎关注我的公众号 IT宅
关于IT宅 文章归档

IT宅中的文章除了标题注明转载或有特别说明的文章,均为IT宅的技术知识总结,学习笔记或随笔。如果喜欢,请使用文章下面提供的分享组件。转载请注明出处并加入文章的原链接。 感谢大家的支持。

联系我们:admin@itzhai.com

Theme by arthinking. Copyright © 2011-2015 IT宅.com 保留所有权利.