内容简介:良好的Commit Message有利于代码审查,能更快速查找变更记录,并且可以直接生成Change log。Commit Message的写法规范:其中 head((): )是必须的,body和footer是可选的。 如果只需要输入header,可以直接使用:
良好的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之后记得让其他同事强制更新本地代码;
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Git提交错误时如何删除Git提交记录
- 分布式系统 - 两段式提交(2PC)和三段式提交(3PC)
- 减半前,比特币开发者代码提交数创历史新高:4月累计提交510次
- 提交任务到Spark
- [译] Commit 提交指南
- Git合并提交
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。