点击关注公众号,“技术干货” 及时达!
最近刚入新项目,线上出了一个bug,Leader让排查。相关代码稍显复杂,想看看git历史记录获取些线索,打开Git Graph
一看,当场石化,一堆像task/10001
、hotfix/0910
、experimental/performance_web-worker
、test1
、test2
命名的分支,提交描述如实现10001需求
、修复线上bug
, 这不都是git规范的反面教材吗?作为一个"砖家"
,我不得不写一篇Git规范,让组员看看什么叫professional
。
为了缓解石化,看看开源项目的分支命名,看着是不是就比较规范?虽然分支格式有些差异,但都能看出分支要实现的功能或要解决的问题。
vue3分支:
element-plus分支:
分析这些开源项目的分支命名,不难发现,Git规范没有标准答案,只有适合、不适合。其目的是让项目分支保
持风格统一, 提升易读性, 降低跟踪成本。
本篇内容将从分支流程、分支命名、commit、辅助工具等四个方面介绍。
当实现新功能或者解决线上问题时,需要创建对应的分支并开发,从开发到测试、发布、上线、问题修复等各个环节,如果没有合理的规范约束,当需要回退、急救问题修复或者跟踪排查时,将会让你事倍功半。对于分支开发规范,就以业界常用的git-flow工具来说,一个Feature从开始到上线结束需要经过如下的流程,element-plus也是采用这样的workflow。
「项目主要使用main、develop两个分支来记录git的历史」:main作为production的发布历史分支,例如上线时会基于main发布v0.1、v0.2;develop作为持续集成的分支,当功能分支feature开发完成后会merge到dev并提交测试流程。
develop分支功能测试完毕,准许进入预发阶段,需要依据develop分支创建一个发布阶段使用的release分支,为了能支持多个功能并行开发,release分支可命名为release/0.1.0
。
「当预发阶段发现任何bug,直接在release分支上修改。当需要上线时,除了将release合并到main分支,特别要注意的是,还需要将其合并到develop,随时让develop保持最新代码。使用main发布正式版本的同时会打tag,如v1.0
、v2.0
。」
如果遇到线上问题,「需要紧急解决,则直接从main拉取hotfix分支」,hotfix也是除了develop外还会从main拉取代码的分支。「当问题解决完了,需要将其同时merge到main和develop分支」。
问题:
「这些问题完全可以丢给git-flow、gitflow vscode extension解决」,可交互式创建feature、hotfix分支,开发人员只用关注需要创建的分支即可,流程控制可交给工具管理。
研发规模稍微大点的公司,一般都会有CI/CD,因此也可以将gitflow流程直接集成到CI/CD。
开源CI/CD平台:国内使用比较多的是Jenkins
和GitLab
查看vue和element-plus分支,一般都有feat、fix、perf等作为分支前缀,业界通用的前缀有:
chore/upgrade-vite
除此之外,部分开源项目也允许以人名作为前缀,例如evan/fix-jsx-dom-augmentation
。
假如现在有新需求:实现一个支持无限加载的list组件,JIRA单号为1000,怎么命名分支?
个人觉得将人名作为前缀,分支名稍显冗长,不如以feat
等type作为前缀来的直接、清晰,开发者信息完全可以根据提交记录跟踪。因此,「功能分支命名建议:以feat作为前缀,分支名由多个单词按确定性、重要性排列,由"-"分隔,不超过4个单词。例如feat/1000-types-vnode-hooks
、feat/v-model-dialog
」
上线后发现问题,测试人员提了bug,单号为2000, 问题是内容没有对齐,修复问题的分支如何命名?
虽然开源项目很多以人名作为前缀,但不建议,一方面冗长,另一方面不够直观,例如evan/list-style-align
,如果加上单号和问题标识,则变为evan/fix-list-style-align-2000
就稍显冗长。
因此,「问题类分支命名建议:以fix作为前缀,分支名由多个单词按问题范围从小到大的单词排列,由-
分隔,不超过4个单词。例如fix/2000-menu-default-opened
、fix/eslint-config-vnode
。」
list用了一段时间,leader提出优化list,降低内存占用,「性能优化分支如何命名?」
「性能相关分支命名建议:以perf作为前缀,分支名由多个单词按模块(page、list、table等)、性能类型(loading、render、momory等)、优化方向进行排列。例如perf/page-render-by-skeleton
、perf/table-loading-lazy
。」
当项目开发到前中期、模块越来越多,需要把项目拆成多包模式,「重构分支如何命名?」
「重构分支命名建议:如果是对模块或组件重构,一般表明影响面即可。例如refactor/select
、refactor/docs-style-update
、refactor/ast
。」
除了以上新功能、问题修复、性能优化这些方面,「其他的改动都可归属到chore类型分支,chore本身就代表琐碎、杂事。例如chore/eslint-upgrade
、chore/vitest-ugrade
、chore/eslint-imports
。」
分支命名最重要不适非的限制使用哪一套方式,整体保持一致就行,不能像以下这样混着用:
「辅助工具:validate-branch-name」,用于校验分支命名。
npm i validate-branch-name -g
在.husky
(装可参考下文的commit规范
)下定义pre-commit文件,并添加如下内容:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
# validate branch name before commit
npx validate-branch-name
在package.json
文件添加内容:
"validate-branch-name": {
"pattern": "^(master|main|develop){1}$|^(feat|fix|hotfix|release|perf|refactor|chore)/.+$",
"errorMsg": "分支命名不规范,请修正!"
}
假如提交分支test-vueuse
代码,执行git commit -m 'feat:添加vueuse测试用例'
,则会报错:
可执行git branch -m branchName
修改分支命名,再重新提交。
代码提交规范和分支命名相关联,但比分支命名分的更加明细,大多数开源框架都采用angular.js指定的提交格式,类型包含:
代码提交信息一般由多个部分组成,分别是Type、Scope、Subject、Body、Footer, 先看下开源项目提交案例:
包含Type、Scope、Subject、Footer
包含Type、Scope、Subject、Body
结合上面两个案例,再来理解这几部分的含义:
feat(compiler-doem)
、fix(table)
close #11873
,github在关联issue时,可自动添加Footer信息。所以,需要人添加的部分一般为Type、Scope、Subject即可,例如:
feat(components): [dialog] Dialog can drag overflow the viewport (#15643)
feat(components): [table] add `filterClassName` props in TableColumn (#15389)
test(components): [select-v2] backspace should not delete disabled tag (#15552)
refactor(components): [drawer] use setup (#15556)
perf( runtime-core): use `apply` to avoid spreading. (#5985)
style(components): [menu] Collapse mode active color (#15343)
chore: update email link in SECURITY.md (#11632) [ci skip]
当修改多包模式下的组件时,可通过Type(package):[componentName] XXXX
形式提交信息,例如feat(components):[table] add header filter props
。
如果完全让人自觉遵守commit规则,这非常不现实,所以还得借助工具提供交互式和校验,如husky、commitizen、git-commit-plugin相关工具打组合拳。
husky安装:
npx husky-init && npm install
validate-branch-name
,在pre-commit添加执行命令。npm install validate-branch-name --save-dev
npx husky add .husky/pre-commit "npx validate-branch-name"
在package.json
文件添加内容:
"validate-branch-name": {
"pattern": "^(master|main|develop){1}$|^(feat|fix|hotfix|release|perf|refactor|chore)/.+$",
"errorMsg": "分支命名不规范,请修正!"
}
3.安装commitizen
npm install commitizen --save-dev
使用cz-conventional-changelog
提供交互描述信息
commitizen init cz-conventional-changelog --save-dev --save-exact
安装完后,可执行cz
、cz commit
、git cz
等指令唤起交互式。
npm install @commitlint/config-conventional @commitlint/cli --save-dev
在项目根目录下新建文件commitlint.config.js
,并添加如下内容:
module.exports = {
extends: ['@commitlint/config-conventional'],
parserPreset: {
parserOpts: {
issuePrefixes: ['#'],
},
}
}
「可根据自身需求来配置Type、Scope等信息,配置详情查看commitlint docs」
执行如下指令,在commit-msg文件添加校验指令。
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit $1'
通过上述的配置,当执行git commit
时,先使用validate-branch-name
检查分支名,再弹出git message交互模式。
prepare-commit-msg
添加如下内容:#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
exec < /dev/tty && npx cz --hook || true
git规范主要覆盖workflow、branch naming、branch commit三个环节:
「要说git规范的作用,虽然决定不了你的上限,但完全能拉低你的技术影响力。」 好的git规范不仅让人看起来赏心悦目,在排查紧急问题时也能达到事半功倍的效果。