Git规范实践

规范说明

git commit message即代码提交历史,错误的提交信息会影响代码的可维护性。在多人协作开发场景下因个人风格各有不同,若无统一的规范则很容易导致混乱。目前规范使用较多的是 Angular 团队的规范

消息提交格式

每个提交消息都包含一个headerbodyfooterheader具有一种特殊的格式,其中包括typescopesubject

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>

为使在各种git工具中更易于阅读,提交消息的任何一行都不能超过100个字符。

Header

  • type
    必须为以下之一开头:

    • feat:一项新的功能feature
    • fix: bug修复
    • docs: 只修改了文档
    • style: 没有代码的更改,样式调整(空白,格式,缺少分号等)
    • refactor: 代码重构,既不修正bug也不增加功能(feature)的更改
    • perf: 改进性能的代码更改
    • test: 添加缺失或更正现有测试
    • build: 影响构建系统或外部依赖项的更改,如:gulp, broccoli, npm
    • ci: 对CI配置文件和脚本的更改,如:Travis,Circle,BrowserStack,SauceLabs
    • chore: 更改构建过程或辅助工具和库,例如文档生成等
    • revert: 如果该提交还原了先前的提交,则应以revert:开头 ,后接reverted commitheader。此外body中应该标明:This reverts commit <hash>,其中hash是要还原的提交的SHA值。
  • scope
    scope是可选的。
    用于辅助说明所要提交代码更改的内容归属,例如可以指明是哪个位置(location)、哪个模块(module)、哪个组件(componet)等。当更改影响的范围不止一个范围时,可以使用*

  • subject
    该主题包含对变更的简洁描述:
    使用现在时态:“change”不是“ changed”也不是“ changes”
    不要大写第一个字母
    末尾没有点(。)

Body

就像在主题(subject)中一样,使用命令式现在时态:“change”而不是“changed”或“changes”。 body应包括改变的动机,并将其与以前的行为进行对比。

Footer

  • 不兼容变动
    如果当前代码与上一个版本不兼容,则 Footer 部分以 BREAKING CHANGE 开头,用空格或两个换行符,后面是对变动的描述、以及变动理由和迁移方法。如fix并携带BREAKING CHANGE信息:
fix: correct spelling of referrer in header

BREAKING CHANGE: Rather than using misspelled "Referer" as name of header,
instead use correct spelling "Referrer". Clients expecting "Referer" will no
longer receive that header  and will presumably not honor the new "Referrer"
until updated to support this new name for this header.
  • 关闭 Issue
    如果当前 commit 针对某个issue,那么可以在 Footer 部分关闭这个关联issue 。
Closes #123

或者关闭多个issue

Closes #123 #456 #789

GitHub关联issue说明:https://docs.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue

项目配置

现在比较流行的方案是约定式提交规范(Conventional Commits),它受到了 Angular 提交准则的启发,并在很大程度上以其为依据。笔者尝试查找了基于非node环境相关的Git规范化的辅助工具或插件,并没有找到很好的解决方案,而我们如果拥有node环境非node项目也可以正常配置执行,只不过在工程中会生成node项目相关的文件,如node_modules文件夹、package.json文件等,因此在项目的版本控制中稍微麻烦一些,根据需要定义自己的ingore文件,处理好项目代码和环境代码的问题。

环境和工具

  • node
  • npm(npx)
  • commitizen/cz-cli: 是一个格式化commit message的工具,可以约束提交者按照制定的规范一步一步的填写commit message。
  • cz-conventional-changelog: 为 commitizen 指定一个 Adapter ,一个符合 Angular 团队规范的 preset(按照我们指定的规范帮助我们生成 commit message)

非node项目

定位到workspace目录(即项目根目录)命令行输入npm init,执行后会出现一系列初始化的提示,可以一直回车至结束。npm init 相关说明:https://www.npmjs.cn/cli/init/

依赖安装

  • 安装commitizencz-conventional-changelog
npm i -D commitizen
npm i -D cz-conventional-changelog
  • 修改package.json文件
    工程的配置示例.png
{
  "name": "testp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "commit": "git-cz"
  },
  "config": {
    "commitizen": {
      "path": "node_modules/cz-conventional-changelog"
    }
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "commitizen": "^4.2.3",
    "cz-conventional-changelog": "^3.3.0"
  }
}

在项目根目录,命令行执行npm run commit,会出现操作步骤提示,按前文所诉填写规范化信息。

操作提示.png

操作提示..png

执行完,sourcetree效果图:
效果图.png

Commit信息校验和拦截

虽然我们在项目中配置了commit,但是如果我执行规范操作,不使用npm run commit提交代码,通过命令行或者Git可视化工具直接commit,那么提交上去的可能是不规范的信息,因此需要对git命令进行拦截,并对message内容做lint操作。

  • lint工具依赖安装
    • commitlint/cli 【命令行工具】
    • commitlint/config-conventional 【校验规则】符合 Angular团队规范。
npm i -D @commitlint/config-conventional @commitlint/cli
  • 修改 package.json,配置commitlint
{
   ...
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "commit": "git-cz",
    "commit-lint": "commitlint -e $HUSKY_GIT_PARAMS"
  },
  "config": {
    "commitizen": {
      "path": "node_modules/cz-conventional-changelog"
    }
  },
  "commitlint": {
    "extends": [
      "@commitlint/config-conventional"
    ]
  },
  ...
}
  • 安装Husky,进行git hooks校验
  npm install husky --save-dev
  • 启用git hooks
npx husky install 

git hooks启用后会在项目根目录下生产.husky的文件夹

image.png

  • 添加commit_msg到husky,用于拦截git commit命令
npx husky add .husky/commit-msg "npm run commit-lint"

执行完成后会生成commit-msg的脚本

commit-msg-shell.png

此时我们在命令行直接执行git commit -m "test message",会被拦截提示提交失败。
image.png

SourceTree的问题

通过上面配置完成后用SourceTree提交代码会发现运行错误。

image.png

这是因为SourceTree没有读取到环境变量信息,需要在commit-msg脚本中添加环境变量的配置。
image.png

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

export PATH=/usr/local/bin:$PATH
npm run commit-lint --silent

此刻再运行,已成功拦截


image.png

说明

  • cz-conventional-changelog提交信息提示和@commitlint/config-conventionallint规则都可以设置自定义的Adapter,可以根据自己需要配置适合自己团队的规范。
  • 文章截图是以非node(Android)项目的视角进行的配置,其他项目也类似,只要使用的Git进行的版本控制,都可以实现Commit Message的规范化校验。
  • 文章依赖的是Mac OS,Windows下类似,所有的依赖库在Windows下也可运行工作,只不过环境的配置方式不同而已。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,064评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,606评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,011评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,550评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,465评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,919评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,428评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,075评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,208评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,185评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,191评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,914评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,482评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,585评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,825评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,194评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,703评论 2 339

推荐阅读更多精彩内容