博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个维护版本日志整洁的Git提交规范
阅读量:7126 次
发布时间:2019-06-28

本文共 7155 字,大约阅读时间需要 23 分钟。

1 关于提交日志规范

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

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

(
):
<空行>
<空行>
复制代码

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

git commit -m复制代码

命令提交。

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

git commit复制代码

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

1.1 Header

1.1.1 Type

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

feat:新功能(feature)fix:修补bugdocs:文档(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 availableBreaks $browser.onHashChange, which was removed (use onUrlChange instead)---------fix($compile): couple of unit tests for IE9Older IEs serialize html uppercased, but IE9 does not...Would be better to expect case insensitive, unfortunately jasmine doesnot allow to user regexps for throw expectations.Closes #392Breaks foo.bar api, foo.baz should be used instead---------eat(directive): ng:disabled, ng:checked, ng:multiple, ng:readonly, ng:selectedNew 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 bindingsChanged the isolate scope binding options to:  - @attr - attribute binding (including interpolation)  - =model - by-directional model binding  - &expr - expression execution bindingThis change simplifies the terminology as well asnumber of choices available to the developer. Italso supports local name aliasing from the parent.BREAKING CHANGE: isolate scope bindings definition has changed andthe 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项目中,我们可以通过使用 + 进行提交日志校验,校验不通过的将被拒绝提交。原理是通过NodeJs项目编译,把NodeJS的校验脚本写到.git/hooks/目录下的勾子文件中,这样每次执行git commit命令都会执行这个校验,不过这种方式依赖于Node环境,并且每个Git项目都需要引入对应的npm模块进行编译,对于比较多微服务项目的情况来说使用不太方便。

为此,编写了插件, 该插件有如下特点:

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

配置完这个,当我们通过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

首次发布于:

转载于:https://juejin.im/post/5bf7b2e9e51d45213e57be92

你可能感兴趣的文章
python练习题总结
查看>>
多线程编程之保护性暂挂模式
查看>>
Python基础之基本数据类型
查看>>
Debian升级
查看>>
Git之忽略文件(ignore file)
查看>>
mysql-8.0.11-winx64安装
查看>>
核心动画中的几种layer
查看>>
IOS 本地通知
查看>>
正则表达式匹配多个字符串中的一个
查看>>
C#实例:5个.net经典例子(窗体与界面设计)
查看>>
css的理解 ----footrt固定在底部
查看>>
angular之$watch方法详解
查看>>
OpenCV中Mat的列向量归一化
查看>>
Spark+ECLIPSE+JAVA+MAVEN windows开发环境搭建及入门实例【附详细代码】
查看>>
提升编程能力的11个技巧
查看>>
popoverController使用注意
查看>>
关于Could not parse configuration: /hibernate.cfg.xml的问题
查看>>
python-第三方模块
查看>>
开启telnet
查看>>
个人冲刺第四天
查看>>