jiayisheji / blog

没事写写文章,喜欢的话请点star,想订阅点watch,千万别fork!

Home Page:https://jiayisheji.github.io/blog/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

GET新技能之Git commit message

jiayisheji opened this issue · comments

commented

前言

程序员是一个千变万化但是又不离其中的职业,能够实现各种各样的功能,实现的方法也是各种各样,而最佳实践又是很多程序员比较认可和遵守的一些规则,规范可能并不会带来直接的利好,但是随着工程的扩大,团队多人协作,这些良好的习惯可能会带来很好的优势,Eslint是目前最受欢迎前端js规范风格检查工具之一。只从用了它,我就爱上了它。
我总是在思考一个问题,怎么规范git提交消息的格式,怎么去做一个提交版本日志。

背景

以前没有怎么注意Angular的github那些commit message信息,因为英文渣渣,反正也看不懂写啥。经常需要提交Git commit message,每次commit message很头疼,经常只是简单描述一下,或者直接偷懒写当前时间了,回去看自己commit message,真是不知道在说什么。一直想找一个规范来规矩一下自己,发现Angular的Git commit message很特别,它是这样的,举例:

build: switch from npm to yarn (#19328)
docs: add 'bazel' as an Angular component (#19346)
refactor(compiler): bump metadata version to 4 (#19338)
feat(tooling): Add a .clang-format for automated JavaScript formatting.

我当时也看不懂,大概以为就是这样的格式功能:描述(#xxx【不知道说啥的】)
然后我就根据这个猜想写了一个自己草稿规范:

add: 提交
update:更新
remove:移动
delete:删除
feature: 功能
change:修改
fix:修复bug

大概就这几个,每次提交都是这样结构add 添加一个新文件,好像没有毛病。
直到国庆在家没事做,点到Angular的github的CONTRIBUTING.md,才发现我好方。

为什么要工作流规范

在一家公司开始只有我一个做前端开发,后来陆续有了其他多人,这就是所谓开发团队了。一个人开发做事可以随心所欲,啥都可以无所谓,但是遇到一起合作的团队了,就需要正视一些问题,比如代码规范,编码风格,命名规范,注释说明等等,都不是一个人那么随便了。因为你的一举一动,会影响你的同学开发效率。你的同学一举一动,会影响你的开发效率。一段莫名其妙的代码让程序挂了,一段没有注释代码,你看着懵逼。vscode一个不错的编辑器,里面有个插件【Git Lens】很神一样存在,你可以看清楚是哪个二货提交这段垃圾代码,哪个大牛写这段神奇的代码。

那么提交一个标准消息的格式目的是什么:

  • 统一团队Git commit日志标准,便于后续代码review,版本发布以及日志自动化生成等等。
  • 统一团队的Git工作流,包括分支使用、tag规范、issue等
  • 统一团队风格,看上去像是一个人写的

提交消息格式

每个提交消息由title(标题),body(正文)和footer(页脚)组成。标题具有特殊格式,包括type(类型),scope(范围)和subject(主题):

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

标题

标题是必需的,标题的范围是可选的。

任何一行的提交信息都不能超过100个字符!这样可以让消息在GitHub以及各种git工具中更容易阅读。

类型

必须是以下之一:

  • build:影响构建系统或外部依赖关系的更改(示例范围:gulp, broccoli, npm)
  • ci: 更改我们的配置文件和脚本(示例范围:Travis, Circle, BrowserStack, SauceLabs)
  • docs: 仅文档更改,比如README, CHANGELOG, CONTRIBUTE等等
  • feat: 一个新功能
  • fix: 一个错误修复
  • perf: 一个改进性能的代码更改,比如提升性能、体验
  • refactor: 代码更改,既不修复错误也不添加功能
  • style: 不改变代码逻辑,仅仅修改代码风格(空格,格式化,分号分号等)
  • test: 添加缺失测试或更正现有测试(测试用例,包括单元测试、集成测试等)
  • revert: 回滚到某一个版本(带上版本号)

范围

范围应该是受影响的npm包的名称(由人们阅读从提交消息生成的更改日志所感知的范围。
以下是支持的范围的列表:(这里也指业务模块)

  • user 用户
  • pay 支付
  • product 产品
  • article 文章
  • core 核心
  • router 路由
  • api 接口
  • doc 文档
  • upgrade 升级计划
  • ...等

主题

主题包含对变更的简明描述:

  • 以动词开头,使用第一人称现在时:"change"(改变 动作) 不是 "changed"(改变 过去式) 也不是 "changes"(改变 三单形式)
  • 不要大写第一个字母
  • 最后没有点(。)

常用表述语:

  • add 添加
  • change 改变
  • update 更新
  • remove 移动
  • delete 删除

正文

  • 使用第一人称现在时,比如使用:"change"(改变 动作) 不是 "changed"(改变 过去式) 也不是 "changes"(改变 三单形式) 。
  • 正文应该包括变化的动机,并与之前的行为进行对比。

页脚

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

页脚应包含对问题的结束引用(如果有)。请参照以下格式:

  • close 关闭(动作)
  • closes 关闭(三单形式)
  • closed 关闭(过去式)
  • fix 修理(动作)
  • fixes 修理(三单形式)
  • fixed 修理(过去式)
  • resolve 解决(动作)
  • resolves 解决(三单形式)
  • resolved 解决(过去式)

Example1:

关闭`issue`编号`123`问题

Closes #123

Example2:

关闭并修理`issue`编号`45`问题

Fixes #45

Example3:

解决`issue`编号`55`bug

Resolves #55

Revert

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

revert: feat(pencil): add 'graphiteWidth' option

This reverts commit 667ecc1654a317a13331b17617d973392f415f02.

Body 部分的格式是固定的,必须写成 `This reverts commit <hash>.`,其中的 `hash` 是被撤销 commit 的 SHA 标识符。
如果当前 commit 与被撤销的 commit,在同一个发布(release)里面,那么它们都不会出现在 Change log 里面。如果两者在不同的发布,那么当前 commit,会出现在 Change log 的 `Reverts` 小标题下面。

格式要求:

标题:描述主要变更内容(建议50个字符以内)。

主体内容:更详细的说明文本(建议72个字符以内)。 
需要描述的信息包括:
为什么这个变更是必须的? 它可能是用来修复一个bug,增加一个feature,提升性能、可靠性、稳定性等等
他如何解决这个问题? 具体描述解决问题的步骤
是否存在副作用、风险?

尾部:如果需要的化可以添加一个链接到issue地址或者其它文档,或者关闭某个issue。

Example:

feat(user): add 用户搜索

用户反馈,不能搜索用户。增加搜索功能,可以让用户快速定位某一个用户进行关注或其他后续操作

resolves #55

主体内容和尾部是可选的,标题的范围也是可选的,其他必填的

Git分支与版本发布规范

基本原则:master为保护分支,不直接在master上进行代码修改和提交。

开发日常需求或者项目时,从master分支上checkout一个feature分支进行开发或者bugfix分支进行bug修复,功能测试完毕并且项目发布上线后,将feature分支合并到主干master,并且打Tag发布,最后删除开发分支。分支命名规范:

  • 分支版本命名规则:分支类型 分支发布时间 分支功能。比如:feature_20170401_fairy_flower
  • 分支类型包括:feature、 bugfix、refactor三种类型,即新功能开发、bug修复和代码重构
  • 时间使用年月日进行命名,不足2位补0
  • 分支功能命名使用snake case命名法,即下划线命名。

Tag包括3位版本,前缀使用v。比如v1.2.31。Tag命名规范:

  1. 新功能开发使用第2位版本号,bug修复使用第3位版本号
  2. 核心基础库或者Node中间件,可以在大版本发布,请使用灰度版本号,在版本后面加上后缀,用中划线分隔。alpha或者beta后面加上次数,即第几次alpha:
- v2.0.0-alpha-1
- v2.0.0-belta-2

软件的生命周期中一般分4个版本:

  1. alpha版:内部测试版。
  2. beta版:公开测试版。
  3. rc版:全写:Release Candidate(候选版本)。
  4. stable版:正式发布稳定版。

版本正式发布前需要生成changelog文档,然后再发布上线。

生成changelog文档

install

npm install -D conventional-changelog-cli
or 
npm install -g conventional-changelog-cli

这不会覆盖任何以前的更改日志。以上生成基于自上一个符合“特征”,“修复”,“性能改进”或“突破更改”的模式的最后一个标记之后的提交的更改日志。

run

如果你第一次使用这个工具,想要生成所有以前的更改日志,你可以做

conventional-changelog -p angular -i CHANGELOG.md -s -r 0

也可以添加到package.jsonscripts:

"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0"

然后

npm run changelog

推荐工作流程

  1. 修改代码
  2. 提交代码
  3. 更新package.json版本号
  4. conventionalChangelog生成changelog文档
  5. 提交package.json和CHANGELOG.md文件
  6. 打Tag
  7. Push代码