Git规范

1,850 阅读9分钟

首先声明一点,这里的规范只是建议,仅供参考。

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 的格式

参考资料 - @commitlint/config-conventional

一个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 流程是什么样的,仅供参数。

  1. PD 确定一个功能需求并进行合理地拆分成独立的小需求后,下发给开发同学,同时输出 PRD 文档,之后 UI/UX 出设计和交互稿,需要注意的是,如果交互或逻辑复杂的情况下,一定要交互稿,没资源的情况下至少得出个流程图,切记全靠嘴输出,否则需求延期的概率很大。
  2. 开发同学拿到需求后,从编码的维度上进行再次拆分,最简单的如:首先完成静态页,再添加功能逻辑和mock 数据,最后前后端联调打通整个流程。这一步,前端建议输出一个「前端系统分析文档」,记录内容包括:功能需求背景和价值,技术实现方案,技术难点和坑,发布计划(如果有)等等。这个过程看着会浪费一些时间,实际上对公司和自己的价值非常大,不详述了。
  3. 进入编码阶段,首先在代码库中创建一个 issue,示例如下:

将所有的内容填写完整。注意,这个 issue 将跟踪和记录需求的整个生命周期,也可以用来管理需求的进度和技术讨论。

  1. 创建本地开发分支,进行开发。开发完成后,发起 MR,进行 code review,合并到主开发分支并关闭关联的 issue。
  2. 提醒 PR 和 UI 进行验收,没有问题后发布到正式环境(一般是先灰度后全量)。注意,发布到正式环境后,开发者最后自行验证下功能,排除环境导致的异常。
  3. 完善「前端系统分析文档」。

可以发现,在整个流程中“小细节”不少,但这些都是实打实的从中大型的项目实践总结出来的。而且对 LCC 来说,「流程规范化」的趋势也越来越明显。

其它

技巧

  1. 使用快捷键

Mac + zsh:

在 Mac 中,如果同时使用了 zsh,在终端中输入:alias,可以发现内置了很多 Git 的快捷方式(别名),直接使用就好。

window 11 + powerShell:

在终端中输入:alias,也内置了很多 Git 的快捷方式(别名)。

自定义别名:

  • 参考这里
  • 可以在终端中自行配置别名的方式。

分支策略

  1. 一个受保护的主分支 master(or main),仅用来发布新版本到生产环境,禁止强制提交。
  2. 一个开发分支 dev,日常开发时所有代码都合并到该分支上,当需要正式“发版”时,对代码核心逻辑进行 code review 后,将 dev 分支合并到主分支上。
  3. 多个 feature/bug 分支,开发完成后合并到 dev 分支上。

rebase(变基)

  1. rebase 操作的特点:
  • 优点是把分叉的提交历史“整理”成一条直线,看上去更直观;
  • 缺点是本地的分叉提交已经被修改过了。
  1. rebase 操作可以把本地未 push 的分叉提交历史成直线,目的是便于我们在查看历史提交的变化和 code review,因为分叉的提交需要三方对比。

要点

  1. Git 跟踪和管理的是修改,而非文件。
  2. Git 标签是版本库的快照,本质是指向某个 commit id 的指针,好处是「语义化」更好,便于记忆。

参考资料

  1. 廖雪峰 Git 教程
  2. git 工作流程
  3. Commit message 和 Change log 编写指南