首先声明一点,这里的规范只是建议,仅供参考。
Git 规范列表
命名规范
1. 新建分支命名
- 方式一:[分支类型]/[开发者名称前缀][功能描述][创建日期]
说明:
-
- 分支类型,如:feature, hotfix, docs, style等;
- 开发者名称前缀,如:用「fj」表示"fujia" 。在很多人协作开发或跨项目开发时,为了避免过多的开发分支,不利于管理,有些场景下需要多个开发者共用一个开发分支;
- 创建日期,可选;
- 方式二:[issue number]-[功能描述]
说明:
-
- issue number,即 issue 的索引,注意,这需要开发者先创建一个对应的issue,然后再创建对应的分支;
- 功能描述,建议与 issue 的标题保持一致,尽可能简洁且语义准确。
建议:开发分支命名应该尽可能的完整,语义清晰。 一个明显的好处是,当上线的功能有些问题需要快速定位时,你使用git branch命令查看分支列表,可以快速从中找到对应的开发分支,而不是对着几十个只有一个单词的分支名一脸懵逼。
2. 新建文件命名
参考内容:vuejs2/style-guide
- 尽可能的语义完整和准确,即可以通过文件名大致能猜到文件的功能,这对像 LCC 这样大型的单体应用来说非常重要;
- 如果文件是组件,命名应该以高级别的 (通常是一般化描述的) 单词开头,以描述性的修饰词结尾。
示例如下:
`反例:`
`components/`
`|- ClearSearchButton.vue`
`|- ExcludeFromSearchInput.vue`
`|- LaunchOnStartupCheckbox.vue`
`|- RunSearchButton.vue`
`|- SearchInput.vue`
`|- TermsCheckbox.vue`
`好例子:`
`components/`
`|- SearchButtonClear.vue`
`|- SearchButtonRun.vue`
`|- SearchInputQuery.vue`
`|- SearchInputExcludeGlob.vue`
`|- SettingsCheckboxTerms.vue`
`|- SettingsCheckboxLaunchOnStartup.vue`
提交规范
1. 快速开发,多次 commit,快速合并到主开发分支,这对多人协作开发非常重要。
如何从代码层面拆分需求?可以参考:react 哲学
「快速开发,多次commit」即开发者要将一个大的功能需求拆分为更加细粒的小需求,每完成一个小需求后就要 commit 一次,好处如下:
-
开发的过程就是一个不断整理需求的过程,思路清晰,结构明确;
-
帮助快速排查、定位问题;
-
当代码被改乱需要回滚时,可以更加精细的控制回滚节点;
-
非常有利于 code review,特别是项目排期紧张的时候,基本只会 review 核心逻辑,通过 commit 对开发过程进行隔离,我们就可以清晰地看到它。
「快速合并到主开发分支」即开发者在完成一个功能需求或独立的一部分(以web开发为例,完成了静态页的开发就可以认为是功能独立的一部分)时,就需要将本地开发分支合并到主开发分支,这一点非常重要。
好处如下:
- 避免团队其他成员合并时有大量的冲突, 这是主要也是必须要解决的问题。事实上,团队越大、项目规模越大以及项目自身的耦合越紧,这样做的价值越大。当然,合并冲突是无法避免的,但是冲突的「量」要严格控制,想想如果你用一个小时修复了一个小bug,结果需要三个小时来解决合并冲突,任谁都得“凌乱”吧;
- 进度可见,解决依赖。 「进度可见」面向的是 PD/UI/Leader 等,有利于他们把握进度和实时做出微调。「解决依赖」面向的是其他的开发者,一个场景是其他开发者依赖你的功能时,可以快速处理这种依赖,“贯通”整个功能流程,避免一些mock或hack的操作。
强烈建议:把不断同步主开发分支和合并本地开发分支到主开发分支作为使用 Git 流的最佳实践之一,并形成一种强意识,即使在个人项目中也建议认真践行。
2. commit message 规范
一般来说,commit message 应该清晰明了,说明此次提交的目的。
2.1 制定 message 规范的好处:
- 提供了更多的历史信息,方便快速浏览
举个例子,在 LCC 项目的终端输入命令:git log --pretty=format:%s,结果如下:
可以看到,只需要看行首,就可以大致知道每一次 commit 的目的。
-
过滤某些commit(比如文档改动),便于快速查找信息,如命令:
git log HEAD --grep fix。 -
可以直接从commit生成Change log,Change Log 的作用是在发布新版本时,说明与上一个版本差异的文档。
2.2 message 的格式
一个commit message 通常包括三个部分:Header, Body 和 Fooder,只有 Header 是必须的。注意,各个部分都不建议太长(推荐:72或100个字符,@commitlint/config-conventional 的默认限制是100),原因是自动换行会影响美观。
Header 只有一行,包括三个部分:type(必须),scope(可选)和 subject(必须)。
type: 说明 commit 的类别,如果使用 @commitlint/config-conventional 库,那么只能使用下面的标识:
- build - 构建过程相关;
- chore - 辅助工具的变动;
- ci - 持续集成的配置或改动相关,如修改了 gitlab-ci.yml 文件;
- docs - 文档更新;
- feat - 新功能(feature);
- fix - 修复bug;
- perf - 性能优化;
- refactor - 重构(即不是新增功能,也不是修改bug的代码变动);
- revert - 一种特殊情况,如果当前 commit 用于撤销以前的 commit,则必须以revert:开头,后面跟着被撤销 Commit 的 Header;
- style - 格式(不影响代码运行的变动);
- test - 增加测试;
scope: 用于说明 commit 影响的范围,如:数据层,控制层和视图层等,根据项目而定,这里我们学习下 vue.js 的代码提交:
subject: commit 目的的简短描述,不超过50个字符,书写建议:
- 以动词开头,使用第一人称现在时,如 change,而不是 changed 或 changes;
- 第一个字母小写;
- 结尾不加句号(.)。
body 和 footer 这里不详述,可以参考这里。
2.3 使用工具
我们先来看看 LCC 项目,发现它使用了 husky 和 lint-staged 库,但仅仅对文件进行了 「lint」, 并没有对commit message 进行校验,这里建议加上,从流程上进行规范,而不是依赖开发人员的技术水平和意识。推荐使用下面第三方库:
- @commitlint/config-conventional;
- commitlint;
- husky@7.x 或更高;
流程规范
这部分的内容我们将 LCC 项目和 gitlab 来说明,对前端开发来说,一个较为完整的 Git 流程是什么样的,仅供参数。
- PD 确定一个功能需求并进行合理地拆分成独立的小需求后,下发给开发同学,同时输出 PRD 文档,之后 UI/UX 出设计和交互稿,需要注意的是,如果交互或逻辑复杂的情况下,一定要交互稿,没资源的情况下至少得出个流程图,切记全靠嘴输出,否则需求延期的概率很大。
- 开发同学拿到需求后,从编码的维度上进行再次拆分,最简单的如:首先完成静态页,再添加功能逻辑和mock 数据,最后前后端联调打通整个流程。这一步,前端建议输出一个「前端系统分析文档」,记录内容包括:功能需求背景和价值,技术实现方案,技术难点和坑,发布计划(如果有)等等。这个过程看着会浪费一些时间,实际上对公司和自己的价值非常大,不详述了。
- 进入编码阶段,首先在代码库中创建一个 issue,示例如下:
将所有的内容填写完整。注意,这个 issue 将跟踪和记录需求的整个生命周期,也可以用来管理需求的进度和技术讨论。
- 创建本地开发分支,进行开发。开发完成后,发起 MR,进行 code review,合并到主开发分支并关闭关联的 issue。
- 提醒 PR 和 UI 进行验收,没有问题后发布到正式环境(一般是先灰度后全量)。注意,发布到正式环境后,开发者最后自行验证下功能,排除环境导致的异常。
- 完善「前端系统分析文档」。
可以发现,在整个流程中“小细节”不少,但这些都是实打实的从中大型的项目实践总结出来的。而且对 LCC 来说,「流程规范化」的趋势也越来越明显。
其它
技巧
- 使用快捷键
Mac + zsh:
在 Mac 中,如果同时使用了 zsh,在终端中输入:alias,可以发现内置了很多 Git 的快捷方式(别名),直接使用就好。
window 11 + powerShell:
在终端中输入:alias,也内置了很多 Git 的快捷方式(别名)。
自定义别名:
- 参考这里;
- 可以在终端中自行配置别名的方式。
分支策略
- 一个受保护的主分支 master(or main),仅用来发布新版本到生产环境,禁止强制提交。
- 一个开发分支 dev,日常开发时所有代码都合并到该分支上,当需要正式“发版”时,对代码核心逻辑进行 code review 后,将 dev 分支合并到主分支上。
- 多个 feature/bug 分支,开发完成后合并到 dev 分支上。
rebase(变基)
- rebase 操作的特点:
- 优点是把分叉的提交历史“整理”成一条直线,看上去更直观;
- 缺点是本地的分叉提交已经被修改过了。
- rebase 操作可以把本地未 push 的分叉提交历史成直线,目的是便于我们在查看历史提交的变化和 code review,因为分叉的提交需要三方对比。
要点
- Git 跟踪和管理的是修改,而非文件。
- Git 标签是版本库的快照,本质是指向某个 commit id 的指针,好处是「语义化」更好,便于记忆。