Home
avatar

Qiu

Git提交信息规范

AI 总结

基于 Conventional Commits 标准的团队提交规范手册。详述 Header/Body/Footer 结构、Type/Scope 使用规则、正误对比与示例,并附 commitlint + husky 工具链配置及团队最佳实践,可直接作为项目提交规范落地执行。

0. 认识

0.1 类型与语义化版本对应关系

提交类型语义化版本影响
feat次版本号 +1
fix修订号 +1
perf修订号 +1
BREAKING CHANGE主版本号 +1
其余类型不影响版本号

0.2 快速查询速查表

# 新增功能    feat: xxx
# 修复Bug     fix: xxx
# 文档修改    docs: xxx
# 格式调整    style: xxx
# 代码重构    refactor: xxx
# 性能优化    perf: xxx
# 测试相关    test: xxx
# 工程配置    chore: xxx
# CI/CD      ci: xxx
# 回滚提交    revert: xxx

1. 文档概述

1.1 规范目的

本规范基于业界通用的 Conventional Commits 1.0.0 标准制定,同时参考Angular社区成熟的提交约定,旨在统一团队Git提交信息的书写格式与语义标准,实现以下核心目标:

  • 让提交历史具备结构化、高可读性,开发者可快速定位每次提交的核心意图与影响范围,降低代码回溯与问题排查成本
  • 支撑自动化工具链解析,实现自动生成变更日志(CHANGELOG)、自动计算语义化版本号、自动化发布流程,减少人工整理成本
  • 降低代码评审(Code Review)的理解成本,评审者可通过提交信息快速把握改动背景与核心逻辑,聚焦代码质量本身
  • 沉淀项目演进知识,新人可通过规范的提交历史快速梳理项目发展脉络与技术决策背景,降低学习成本

1.2 适用范围

本规范适用于所有使用Git进行版本管理的项目,包括但不限于前端工程、后端服务、移动端应用、工具库/组件库、文档项目、算法项目等。 所有参与项目开发的人员,包括正式开发、外包、实习生、外部贡献者,提交代码至远程仓库时均需遵循本规范。

1.3 参考标准

1.4 为什么需要统一提交规范

在没有统一规范的团队中,提交历史往往存在大量无意义、模糊的内容,例如“修复bug”“更新代码”“调整”“优化一下”,这类提交会带来诸多痛点:

  1. 问题排查效率低:线上出现故障时,无法通过提交主题快速定位引入问题的提交,需要逐行查看代码diff,大幅增加排查时间
  2. 代码评审成本高:评审者无法第一时间理解改动的背景、目的与边界,需要反复沟通确认,拉长评审周期
  3. 版本发布困难:发版时需要人工逐个梳理提交内容,整理变更日志,耗时耗力且容易遗漏重要变更
  4. 知识传承断层:项目交接、新人入职时,混乱的提交历史无法体现项目的演进逻辑与技术决策过程,学习成本极高
  5. 自动化无法落地:非结构化的提交信息无法被工具解析,版本管理、发布流程只能依赖人工,效率低下且易出错

统一的提交规范本质是用极低的书写成本,换取团队长期的协作效率与项目可维护性提升。

1.5 规范设计原则

本规范在制定过程中遵循以下核心原则,兼顾严谨性与灵活性:

  1. 人机可读:提交信息既要让开发者快速看懂语义,也要能被自动化工具准确解析
  2. 最小结构:核心结构仅包含「头部-正文-页脚」三层,学习成本低,上手快
  3. 语义明确:每个类型、字段都有清晰的定义与边界,避免歧义与混用
  4. 可扩展:支持自定义影响范围、自定义页脚元数据,可根据不同团队、不同项目的需求适配
  5. 与版本对齐:提交类型直接对应语义化版本的变更规则,支撑自动化版本号计算

2. 提交信息完整结构

标准的约定式提交信息由三部分组成:头部(Header)正文(Body)页脚(Footer),各部分之间通过严格的空行分隔。 完整语法结构如下:

<类型>[可选 影响范围][!]: <简短描述>

[可选 正文]

[可选 页脚]

2.1 头部(Header)

头部是提交信息的唯一必填部分,单行书写,是提交信息的核心摘要,包含三个字段:类型(type)、影响范围(scope)、简短描述(subject)。

2.1.1 格式约束

  • 总长度建议不超过 72字符:该约定源自早期终端80字符的显示宽度,扣除Git日志自带的哈希占位、缩进后,72字符可保证在终端中单行完整显示,避免自动折行影响阅读
  • type 与左括号之间无空格,右括号后紧跟冒号,冒号后必须有且仅有一个空格
  • scope 为可选字段,无明确影响范围时可省略括号部分,直接写 <type>: <subject>
  • 包含破坏性变更时,可在范围后、冒号前增加 ! 标记,用于醒目提示不兼容变更

2.1.2 字段职责

  • type:标识提交的性质与类别,从规定的枚举值中选择,是语义解析的核心依据
  • scope:标识提交影响的业务模块、组件或范围,用于快速定位改动区域
  • subject:提交内容的高度概括,一句话说明本次提交的核心改动

2.2 正文(Body)

正文是可选部分,用于详细描述本次提交的背景、改动逻辑、实现原理、注意事项等补充信息,是提交价值的重要载体。

2.2.1 格式约束

  • 必须与头部之间间隔一个空行,否则Git会将其识别为头部的一部分
  • 每行长度建议不超过72字符,超长内容主动换行,保证终端阅读体验
  • 支持使用Markdown列表、分段等格式增强可读性,推荐使用无序列表梳理要点
  • 正文内容可自由扩展,没有长度上限,但需简洁、有信息量,避免冗余

2.2.2 核心写作原则

正文重点说明「为什么改(Why)」,而非「改了什么(What)」。 代码diff可以直观展示所有改动的内容,但无法体现改动的动机、背景、技术选型的权衡过程、潜在的风险与注意事项——这些信息是项目的宝贵知识资产,也是提交正文的核心价值。半年后回溯代码时,正文能帮你快速理解当时的决策逻辑,避免重复踩坑。

2.3 页脚(Footer)

页脚是可选部分,用于标注破坏性变更、关联工单/Issue、回滚说明、协作信息等元数据,是自动化工具解析的重要依据。

2.3.1 格式约束

  • 必须与正文之间间隔一个空行;无正文时,与头部之间间隔两个空行
  • 每行脚注包含一个令牌(Token),后跟 :# 作为分隔符,再紧跟对应的值
  • 令牌名称推荐使用连字符 - 分隔单词(如 Reviewed-by),BREAKING CHANGE 是唯一例外,使用全大写空格分隔
  • 页脚的值支持多行内容,后续行需保持缩进,直到下一个令牌出现为止

2.3.2 通用页脚字段

字段名作用示例
BREAKING CHANGE标记破坏性不兼容变更,对应语义化版本主版本号递增BREAKING CHANGE: 移除v1版本用户接口,不再兼容旧版SDK
Closes / Fixes关联并自动关闭代码仓库的Issue/工单Closes #123, #456
Refs引用相关Issue/文档,但不关闭Refs #789
Reverts标记本次提交为回滚操作,指明被回滚的提交哈希Reverts: 7a3f2d9c
Reviewed-by标注代码评审人Reviewed-by: 张三 <zhangsan@example.com>
Co-authored-by标注共同作者,用于多人协作的提交Co-authored-by: 李四 <lisi@example.com>
Signed-off-by签署开发者原创声明(DCO),开源项目常用Signed-off-by: 王五 <wangwu@example.com>

3. 类型前缀(Type)全解析

type 用于标识本次提交的核心性质,必须从规定的枚举值中选择,统一使用小写英文,不得自定义未约定的类型。

3.1 核心类型详解

3.1.1 feat:新增功能

  • 定义:面向产品用户、面向外部调用者的新增功能、新增特性、新增API,对应语义化版本的 次版本号(MINOR) 递增
  • 判定标准:用户可感知到新的能力;对外暴露的接口新增了方法/字段
  • 适用场景
    • 新增用户注册、登录等业务功能
    • 新增数据导出、报表生成等产品能力
    • 新增对外API接口、新增SDK方法
    • 新增页面、新增组件、新增配置项
  • 反例
    • 修复功能bug不算feat,属于fix
    • 新增内部工具函数、不对外暴露的辅助方法不算feat
    • 重构现有功能、没有新增能力不算feat

3.1.2 fix:修复问题

  • 定义:修复面向用户的Bug、逻辑错误、功能异常,对应语义化版本的 修订号(PATCH) 递增
  • 判定标准:现有功能与预期不符,修复后回归正确行为
  • 适用场景
    • 修复登录态失效、订单状态不同步等业务bug
    • 修复页面样式错乱、交互异常等前端问题
    • 修复接口报错、数据计算错误等后端问题
    • 修复兼容性问题、边界场景异常
  • 反例
    • 代码格式调整、缩进修改不算fix
    • 重构代码逻辑、行为没有变化不算fix
    • 修复测试用例、修复文档错误不算fix

3.1.3 docs:文档变更

  • 定义:仅修改文档、注释类内容,不影响任何业务代码与运行逻辑
  • 判定标准:代码行为完全不变,仅修改文字说明类内容
  • 适用场景
    • 更新README.md、项目说明文档、部署文档
    • 修改API接口文档、使用手册、开发规范
    • 补充、修改代码注释
    • 修改CHANGELOG、版本说明
  • 反例
    • 修改代码逻辑顺带修改注释,以主改动为准,不算docs
    • 修改代码中的文案、提示语,属于业务改动,不算docs

3.1.4 style:代码格式调整

  • 定义:不改变代码逻辑、不影响功能的格式类、风格类调整,仅影响代码外观
  • 判定标准:代码编译、运行后的行为完全不变,只是排版、格式、命名风格变化
  • 适用场景
    • 调整代码缩进、空格、换行、分号补全
    • 按照ESLint/Prettier规范格式化代码
    • 修改变量命名风格(如统一驼峰命名)、调整代码顺序
    • 移除多余空行、补充收尾空行
  • 反例
    • 修改CSS业务样式、UI视觉效果不算style,属于feat或fix
    • 修改变量名导致逻辑变化、重构代码结构不算style

3.1.5 refactor:代码重构

  • 定义:既不新增功能、也不修复Bug的代码结构/逻辑改动,不改变对外的行为与接口
  • 判定标准:外部功能完全不变,内部实现优化、结构调整、代码质量提升
  • 适用场景
    • 抽离公共工具函数、公共组件,消除重复代码
    • 重构代码结构、拆分大函数/大组件、优化模块划分
    • 重命名变量、函数、类,提升代码可读性
    • 替换技术实现方案(如用Map替换对象),但行为不变
    • 移除废弃的冗余代码
  • 反例
    • 新增功能不算refactor
    • 修复bug不算refactor
    • 专门的性能优化不算refactor,归为perf

3.1.6 perf:性能优化

  • 定义:专门用于提升运行性能的提交,属于refactor的一个特殊子类,对应语义化版本的 修订号(PATCH) 递增
  • 判定标准:有明确的性能收益,如加载速度提升、内存占用降低、响应时间缩短
  • 适用场景
    • 优化图片加载、资源压缩,提升页面加载速度
    • 优化算法时间复杂度、减少循环次数
    • 优化接口响应速度、减少数据库查询
    • 降低内存占用、修复内存泄漏
  • 反例
    • 普通代码重构、没有明确性能收益不算perf
    • 功能改动带来的附带性能提升不算perf

3.1.7 test:测试相关

  • 定义:新增、修改测试用例与测试相关代码,不影响业务功能
  • 判定标准:仅改动测试代码,业务代码完全不变
  • 适用场景
    • 新增单元测试、集成测试、E2E测试用例
    • 修改测试用例、更新测试Mock数据
    • 调整测试配置、测试框架、测试脚本
    • 补充测试覆盖率
  • 反例
    • 修复业务bug导致测试用例同步修改,以主改动为准,不算test
    • 测试环境的业务代码调试不算test

3.1.8 chore:工程/工具变更

  • 定义:构建流程、依赖管理、脚手架配置等工程化改动,不影响业务代码与用户功能
  • 判定标准:对业务功能、产品逻辑完全无影响,属于工程基建类改动
  • 适用场景
    • 升级/降级npm/maven等依赖包
    • 修改webpack/vite/rollup等构建工具配置
    • 修改.gitignore、.eslintrc等工程配置文件
    • 修改项目构建脚本、发布脚本
    • 调整项目目录结构(不涉及业务逻辑变动)
  • 反例
    • 业务代码的配置项修改不算chore
    • CI/CD流水线配置不算chore,归为ci

3.1.9 ci:CI/CD相关

  • 定义:持续集成、持续部署流程的配置变更,属于chore的一个特殊子类
  • 判定标准:仅修改CI/CD相关的配置与脚本
  • 适用场景
    • 修改GitHub Actions、GitLab CI、Jenkins流水线配置
    • 修改Docker构建脚本、镜像配置
    • 调整自动化测试、自动化发布流程
    • 修改CI环境变量、执行步骤
  • 反例
    • 本地构建脚本修改不算ci,归为chore
    • 业务代码的部署配置不算ci

3.1.10 revert:回滚提交

  • 定义:撤销之前的某一次或多次提交,回滚代码变更
  • 判定标准:通过 git revert 命令生成的回滚提交,手动修改代码回退不算
  • 规范格式
    revert: 回滚"feat: 新增文章评论功能"
    
    Reverts: 7a3f2d9c
    原因:评论功能上线后出现性能问题,临时回滚优化
  • 注意:回滚多个提交时,需在页脚中列出所有被回滚的提交哈希,并说明回滚原因

3.2 易混淆类型对比

场景正确类型错误类型说明
修改CSS样式,优化按钮显示效果feat/fixstylestyle仅指代码格式,业务样式改动属于功能范畴
抽离公共工具函数,优化代码复用refactorfeat没有新增用户可感知的功能,属于代码重构
升级Vue版本,兼容原有代码chorerefactor依赖升级属于工程化改动,不涉及业务逻辑重构
修复ESLint报错,调整代码格式stylefix代码规范问题不属于业务bug,属于格式调整
优化接口查询速度,减少响应时间perfrefactor有明确性能收益的优化,优先归为perf
修改Jenkins流水线构建步骤cichore持续集成相关的专属类型,优先用ci
修改README中的接口文档docschore文档类改动专属类型,优先用docs

3.3 类型与语义化版本对应关系

提交类型语义化版本影响说明
feat次版本号 +1(MINOR)新增功能,向前兼容
fix修订号 +1(PATCH)修复bug,向前兼容
perf修订号 +1(PATCH)性能优化,向前兼容
包含 BREAKING CHANGE主版本号 +1(MAJOR)破坏性变更,不向前兼容
docs/style/refactor/test/chore/ci/revert不影响版本号不涉及用户功能变更

4. 影响范围(Scope)命名指南

scope 用于标明本次改动影响的业务模块/组件,为可选字段,用于帮助开发者快速定位改动区域,尤其适合中大型项目。

4.1 命名原则

  1. 业务优先:优先按业务模块划分,而非技术分层,例如 user(用户模块)、order(订单模块),而非 apiutils
  2. 保持统一:同一模块的命名在项目内保持唯一,避免出现 user/User/user-center 多种写法
  3. 粒度适中:范围不要太泛(如 common 几乎等于没写),也不要太细(如 login-button),以模块/组件级别为宜
  4. 跨模块处理:改动涉及多个模块时,若有主次则按主模块命名;若为全局改动,可使用 * 或直接省略scope

4.2 层级划分

对于复杂项目,可支持层级化scope,用斜杠 / 或连字符 - 分隔父子模块,团队内统一格式即可。 示例:

  • user/auth:用户模块下的认证子模块
  • order/payment:订单模块下的支付子模块
  • components/button:组件库下的按钮组件

4.3 不同项目类型的命名建议

4.3.1 前端单页应用

  • 业务模块:userordergoodscarthome
  • 基础能力:routerstoreutilscomponentsstylesassets
  • 工程相关:builddeployenv

4.3.2 后端微服务项目

  • 服务维度:user-serviceorder-servicegateway
  • 公共组件:commondbredismq
  • 基础设施:configlogmonitor

4.3.3 Monorepo多包项目

直接使用包名作为scope,例如:

  • @project/components
  • @project/utils
  • @project/cli

4.3.4 移动端应用

  • 页面维度:page-homepage-mine
  • 原生能力:native-devicenative-push
  • 公共组件:componentsutils

4.4 常用示例

feat(auth): 新增短信验证码登录功能
fix(order): 修复订单支付状态不同步问题
refactor(utils): 重构日期格式化工具函数
docs(api): 更新用户模块接口文档
perf(goods): 优化商品列表加载速度
ci(deploy): 调整生产环境部署流程

5. 简短描述(Subject)书写规范

subject 是对本次提交的高度概括,一句话说明改动内容,是头部的核心组成部分,决定了提交信息的第一可读性。

5.1 核心规则

  1. 祈使语气:使用祈使句开头,描述提交“会做什么”,而非“做了什么”。中文使用动词原形开头,如「新增、修复、优化、调整、重构、升级、移除、更新」;英文使用动词原形,如「add、fix、optimize、refactor、remove」
  2. 简洁明确:长度控制在50字符以内,一眼可读,不堆砌细节,细节放在正文
  3. 结尾无标点:末尾不加句号、感叹号、分号等标点符号
  4. 信息完整:包含「改动对象 + 动作 + 结果」,避免模糊表述
  5. 语言统一:团队内统一使用中文或英文,避免中英文混杂

5.2 正误对比

错误示例正确示例错误原因
fix: 修复了一些bugfix: 修复登录页密码输入框无法输入中文描述模糊,无具体信息,无法定位问题
feat: 新增评论功能,还加了点赞和收藏,优化了列表样式feat: 新增文章评论与点赞功能过长,超出长度限制,堆砌多个改动
style: 调整了代码缩进。style: 统一全局代码缩进为2空格结尾带句号,描述不够精准
refactor: 重构了一下工具函数,大概改了点东西refactor: 抽离通用日期格式化工具函数口语化,表述不专业,无有效信息
fix: 我把订单的bug修好了fix: 修复订单创建时金额计算错误第一人称表述,不符合祈使语气规范
feat: 超级好用的新功能上线啦feat: 新增订单批量导出功能情绪化表述,不专业,没有说明具体内容

5.3 常用动词速查表

类别常用动词
新增类新增、添加、增加、引入、支持、上线
修复类修复、解决、修复、修正、恢复
优化类优化、提升、改进、改善、精简、加速
重构类重构、抽离、拆分、整合、重写、调整
删除类移除、删除、废弃、清理、下线
更新类更新、升级、降级、修改、调整
文档类更新、补充、完善、修正、编写
格式类统一、格式化、调整、修正

6. 正文(Body)结构化写作指南

对于简单改动,可省略正文;对于核心功能、复杂Bug修复、架构调整、破坏性变更,必须补充完整正文,说明改动的来龙去脉。

6.1 推荐四段式结构

标准正文建议包含以下四个部分,可根据实际场景裁剪:

(1)背景与动机

为什么要做这次改动?解决了什么问题?需求来源是什么?

  • Bug修复类:说明问题现象、影响范围、根因分析
  • 功能新增类:说明需求背景、用户价值、要达成的目标
  • 重构/优化类:说明现有方案的痛点、优化的必要性

(2)实现方案

核心思路是什么?采用了什么技术方案?关键逻辑是什么?

  • 说明整体实现流程、核心改动点
  • 对比不同方案的权衡,说明选择当前方案的原因
  • 标注关键的技术细节、注意事项

(3)影响范围

改动涉及哪些模块?哪些功能会受影响?有没有副作用?

  • 明确影响的业务范围、代码范围
  • 说明是否有兼容性问题、是否需要同步修改其他模块
  • 标注风险点、需要重点测试的场景

(4)后续计划与备注

有没有遗留问题?后续优化方向是什么?其他需要说明的事项。

6.2 不同场景的写作模板

6.2.1 Bug修复类

fix(order): 修复高并发下订单状态重复更新问题

- 背景:高并发场景下,支付回调多次触发,导致订单状态被重复更新,出现库存扣减异常
- 根因:回调接口未做幂等校验,状态流转没有前置校验,并发请求可同时修改同一订单
- 方案:基于Redis实现回调接口幂等校验,增加订单状态机流转校验,非法状态直接拦截
- 影响:仅影响支付回调流程,不涉及订单创建、退款、发货等其他链路
- 备注:测试环境需配置Redis集群验证幂等效果,压测1000并发无异常

6.2.2 功能新增类

feat(export): 新增订单数据批量导出功能

- 背景:运营同学需要按时间范围导出订单数据做分析,目前只能手动逐条复制,效率极低
- 方案:
  1. 后端支持按时间范围、订单状态筛选导出Excel
  2. 大文件采用分片下载 + 异步生成方式,避免浏览器超时
  3. 导出记录留存7天,支持重复下载
- 权限:仅管理员、运营角色可使用导出功能,普通用户无权限
- 影响:新增导出接口,不影响现有订单相关功能
- 后续:下个版本支持自定义导出字段、支持导出CSV格式

6.2.3 代码重构类

refactor(utils): 重构通用请求工具函数

- 背景:现有请求工具函数封装混乱,错误处理逻辑分散在各个业务代码中,维护成本高
- 方案:
  1. 统一封装请求拦截、响应拦截、错误处理逻辑
  2. 统一错误码提示、异常上报、重试机制
  3. 兼容原有调用方式,逐步替换旧的调用
- 影响:所有使用请求工具的模块,行为完全兼容,无功能变更
- 风险:部分特殊场景的错误处理可能有差异,需重点测试文件上传、下载场景

6.2.4 性能优化类

perf(goods): 优化商品列表首屏加载速度

- 背景:商品列表页数据量大,首屏加载平均耗时3.2s,用户体验差
- 优化目标:首屏加载时间降至1.5s以内
- 方案:
  1. 接口分页查询,首屏只加载第一页数据
  2. 图片懒加载,可视区域外图片延迟加载
  3. 接口数据缓存,5分钟内重复访问直接读缓存
- 效果:首屏加载时间平均降至1.3s,提升约59%
- 影响:仅优化加载逻辑,商品列表功能、交互完全不变

6.3 写作避坑

  1. 不要逐行复述代码:正文不是代码的文字翻译,不要把每行代码做了什么都写出来,重点讲思路与逻辑
  2. 不要只写“做了什么”:重点补充“为什么这么做”,这是diff看不到的信息,也是正文的核心价值
  3. 不要太长:正文是摘要,不是论文,控制在3-5个要点为宜,过长的文档可以链接到需求文档、设计文档
  4. 不要模糊表述:避免“大概、可能、应该、差不多”这类不确定的表述,准确描述改动内容与影响

7. 页脚(Footer)元数据规范

7.1 破坏性变更(BREAKING CHANGE)

当提交包含不兼容的API变更、架构调整、配置废弃时,必须标注破坏性变更,对应语义化版本的 主版本号(MAJOR) 递增。

7.1.1 判定标准

只要满足以下任意一条,即为破坏性变更:

  • 对外API接口签名修改、参数删除/重命名、返回值结构变更
  • 配置项删除、默认值修改、配置格式变更,导致原有配置失效
  • 核心依赖大版本升级,且不向下兼容
  • 数据库表结构变更,不兼容历史数据
  • 面向用户的功能正式下线、移除
  • 公共组件/工具函数的API变更,调用方必须修改代码才能升级

7.1.2 书写规范

refactor(api): 统一用户认证接口响应结构

BREAKING CHANGE: 重构用户认证接口,移除旧版token校验逻辑,不再兼容v1版本SDK
- 变更说明:所有接口响应移除外层code/message包裹,直接返回业务数据,状态通过HTTP状态码标识
- 迁移方案:
  1. 调用方升级至v2版本SDK
  2. 请求头新增 X-App-Version: 2.0 字段
  3. 适配新的响应结构与错误处理逻辑
- 兼容周期:旧版接口保留3个月,2024年12月31日正式下线
- 相关文档:docs/api-migration-v2.md

7.1.3 ! 标记用法

可在 type(scope) 后增加 ! 标记,醒目提示破坏性变更,用于快速识别。 使用 ! 后,页脚仍建议补充详细的 BREAKING CHANGE 说明。 示例:

feat(api)!: 重构用户认证接口v2版本

BREAKING CHANGE: ......

7.2 关联Issue/工单

通过 ClosesFixesResolves 关键字关联代码仓库的Issue,提交合并到主干后会自动关闭对应Issue。

  • 单个Issue:Closes #123
  • 多个Issue:Closes #123, #456, #789
  • 习惯区分:Fixes 多用于修复Bug的Issue,Closes 多用于功能需求、任务类Issue,团队可统一约定

若仅引用相关Issue、不需要关闭,使用 Refs 关键字: Refs #999, 相关需求文档链接

7.3 回滚提交

使用 git revert 回滚提交时,标准页脚需包含 Reverts 字段,指明被回滚的提交哈希,多个提交用逗号分隔。 示例:

revert: 回滚"feat: 新增文章评论功能"

Reverts: 7a3f2d9c, b4d2e8f1
原因:评论功能上线后引发数据库性能问题,临时回滚优化,预计3天后重新上线

7.4 协作元数据

7.4.1 共同作者

多人协作完成的提交,可通过 Co-authored-by 标注所有共同作者,贡献会统计到对应作者的GitHub/GitLab账号。 格式:Co-authored-by: 姓名 <邮箱> 示例:

feat(user): 新增用户中心头像上传功能

Co-authored-by: 张三 <zhangsan@example.com>
Co-authored-by: 李四 <lisi@example.com>

7.4.2 评审人

标注代码评审人员,用于追溯评审责任。 格式:Reviewed-by: 姓名 <邮箱>

7.4.3 测试人

标注测试负责人,确认测试通过。 格式:Tested-by: 姓名 <邮箱>

7.5 自定义扩展

团队可根据自身需求自定义页脚字段,例如:

  • Task: TASK-1234:关联内部项目管理系统的任务编号
  • Doc: docs/xxx.md:关联相关文档
  • Changelog: 新增用户头像上传功能:自定义CHANGELOG显示内容
  • Breaking: 是/否:快速标记是否破坏性变更

自定义字段建议统一命名规范,方便后续工具解析。

8. 完整场景示例集合

8.1 极简提交(仅头部)

适用于小改动、简单修复,日常开发高频使用。

feat: 新增页面返回顶部按钮
fix: 修复手机号正则校验错误
docs: 更新README项目介绍
style: 统一首页代码缩进格式
chore: 升级lodash依赖至4.17.21版本

8.2 带影响范围的提交

feat(auth): 新增第三方微信登录
fix(cart): 修复购物车商品数量加减异常
refactor(router): 优化路由懒加载配置
perf(goods): 优化商品列表图片加载速度

8.3 带正文的完整功能提交

feat(export): 新增订单数据批量导出功能

- 支持按时间范围、订单状态筛选导出Excel格式
- 大文件采用分片下载,避免浏览器内存溢出与超时
- 导出记录留存7天,支持重复下载与状态查询
- 权限控制:仅管理员与运营角色可使用导出功能

Closes #89

8.4 复杂Bug修复提交

fix(payment): 修复高并发下支付回调重复通知问题

- 现象:高并发场景下,支付平台多次回调,导致订单状态重复更新,库存重复扣减
- 根因:回调接口未做幂等校验,状态流转无前置校验,并发请求可同时修改同一订单
- 方案:基于Redis实现回调接口幂等校验,增加订单状态机流转前置校验
- 影响:仅影响支付回调流程,不涉及订单创建、退款等其他链路
- 验证:压测1000并发无重复更新,测试环境验证通过

Fixes #112

8.5 含破坏性变更的提交

refactor(api): 统一用户模块接口响应结构

- 移除所有接口外层code/message包裹结构
- 统一通过HTTP状态码标识请求成功/失败
- 错误信息统一放入error字段,业务数据直接返回
- 统一分页字段命名为total/list

BREAKING CHANGE: 所有用户模块接口响应结构变更,前端调用必须适配
- 迁移步骤:
  1. 移除接口响应的外层data解构
  2. 适配HTTP状态码的错误处理逻辑
  3. 分页字段替换为total与list
- 兼容周期:旧版接口保留3个月,2024年12月31日下线
- 详细文档:docs/api/user-migration-v2.md

Closes #201

8.6 回滚提交

revert: 回滚"feat: 新增文章评论功能"

Reverts: 7a3f2d9cb4e6d3f2a1b0c5d8e9f0a1b2c3d4e5f
原因:评论功能上线后引发数据库慢查询,导致首页响应超时,临时回滚优化
预计重新上线时间:2024-06-20

8.7 多人协作提交

feat(user): 新增个人中心资料编辑功能

- 支持修改头像、昵称、个人简介
- 支持修改绑定手机号与邮箱
- 增加敏感操作二次验证

Co-authored-by: 张三 <zhangsan@example.com>
Co-authored-by: 李四 <lisi@example.com>
Reviewed-by: 王五 <wangwu@example.com>
Closes #76

8.8 CI/CD配置修改

ci: 优化生产环境构建部署流程

- 增加构建缓存,缩短构建时间约40%
- 增加部署前自动化测试校验,测试不通过禁止发布
- 增加灰度发布步骤,支持按比例切流
- 新增部署失败自动回滚机制

9. 常见错误与避坑指南

9.1 格式类错误

错误写法正确写法说明
Feat: 新增功能feat: 新增功能type必须全小写
feat:新增功能feat: 新增功能冒号后必须加一个空格
feat (user): 新增功能feat(user): 新增功能type与括号之间不能有空格
feat(user):修复bugfeat(user): 修复bug冒号后必须加空格
feat( User ): 新增功能feat(user): 新增功能scope内不能有空格
头部后直接写正文,没空行头部与正文之间空一行空行是结构分隔的标识,不能省略

9.2 内容类错误

9.2.1 类型混用

  • 把业务样式修改写成 style:CSS样式是业务功能的一部分,修改样式属于 featfixstyle 仅指代码格式
  • 把依赖升级写成 feat:普通依赖升级属于工程化改动,归为 chore;只有依赖升级带来了明确的新功能,且新功能是本次提交的核心,才用 feat
  • 把重构写成 fix:重构不改变外部行为,没有修复bug,不能用 fix
  • 把测试用例补充写成 test 但同时改了业务代码:以主改动为准,测试代码只是配套修改,不能用 test 类型

9.2.2 描述模糊

避免以下无信息量的描述:

  • “修复了一些问题”、“优化了代码”、“调整了样式”
  • “更新一下”、“改了点东西”、“临时提交”
  • “修复bug”、“优化性能”、“重构代码”

好的描述应该精准、具体,让人一眼知道改了什么地方、什么内容。

9.2.3 提交粒度过大

一个提交包含多个不相关的改动,比如“新增登录功能 + 修复订单bug + 优化首页样式 + 更新依赖”,俗称“大杂烩提交”。

  • 危害:无法回滚单个功能;无法快速定位问题;代码评审困难;提交历史混乱
  • 原则:一个提交只做一件事,不同类型、不同模块的改动尽量拆分提交
  • 技巧:开发过程中随时小步提交,合并到主干前通过 git rebase -i 整理提交历史

9.2.4 提交粒度过细

反过来,也不要拆得太碎,比如改一个错别字提交一次、补一个分号提交一次,过于零散的提交同样会让历史变得混乱。 建议:同类型、同范围的小改动可以合并成一个提交。

9.3 认知类误区

9.3.1 “提交规范是形式主义,没用”

短期看,写规范的提交信息会多花十几秒,但长期来看:

  • 排查线上问题时,通过提交历史快速定位引入点,节省几小时甚至几天
  • 代码评审时,快速理解改动背景,减少反复沟通
  • 新人接手项目时,通过提交历史梳理演进脉络,降低学习成本
  • 自动化生成CHANGELOG、自动版本号,减少发版工作量

提交规范是典型的“短期投入小、长期收益大”的团队协作规范。

9.3.2 “我自己的分支,随便写没关系”

个人开发分支可以临时提交(如WIP),但合并到公共分支(develop、main、master)前,必须整理成规范的提交。 公共分支的提交历史是项目的公共资产,不是个人的记事本,要对所有协作者负责。

9.3.3 “小改动不用讲规范”

规范是统一的习惯,不分大小改动。越是小改动,写规范的成本越低,收益越高。 如果所有小改动都不遵守规范,积累下来提交历史依然会混乱不堪。

10. 自动化工具链配置指南

手动遵守规范依赖人的自觉性,容易出错,推荐通过工具链强制校验,降低心智负担,保证规范落地。

10.1 工具链全景

工具作用
HuskyGit钩子工具,在commit前、提交信息时触发校验
commitlint校验提交信息是否符合规范,不符合则拦截
cz-git + Commitizen交互式提交工具,引导式生成规范提交信息,不用记规则
lint-staged只校验暂存区的文件,配合ESLint/Prettier做代码格式化
standard-version基于提交历史自动生成CHANGELOG、自动计算版本号

10.2 Husky + commitlint 强制校验

10.2.1 安装依赖

npm install -D @commitlint/cli @commitlint/config-conventional husky

10.2.2 初始化Husky

# 初始化husky
npx husky install

# 配置package.json脚本,npm install后自动初始化husky
npm set-script prepare "husky install"

10.2.3 添加commit-msg钩子

npx husky add .husky/commit-msg "npx --no -- commitlint --edit $1"

10.2.4 创建commitlint配置文件

项目根目录新建 commitlint.config.js

module.exports = {
  // 继承官方约定式提交规范
  extends: ['@commitlint/config-conventional'],
  // 自定义规则
  rules: {
    // type类型枚举,可根据团队需求增减
    'type-enum': [
      2, // 0: 关闭, 1: 警告, 2: 错误
      'always',
      [
        'feat',
        'fix',
        'docs',
        'style',
        'refactor',
        'perf',
        'test',
        'chore',
        'ci',
        'revert'
      ]
    ],
    // type小写
    'type-case': [2, 'always', 'lower-case'],
    // type不能为空
    'type-empty': [2, 'never'],
    // subject不能为空
    'subject-empty': [2, 'never'],
    // subject最大长度50
    'subject-max-length': [2, 'always', 50],
    // 正文每行最大长度72
    'body-max-line-length': [2, 'always', 72],
    // 冒号后必须有空格
    'colon-space': [2, 'always'],
    // scope用括号包裹,中间无空格
    'scope-case': [2, 'always', 'lower-case']
  }
};

10.2.5 效果

配置完成后,提交信息不符合规范时,会直接拦截并报错,提示具体哪里不符合,修正后才能提交成功。 示例报错:

⧗   input: 修复登录bug
✖   subject may not be empty [subject-empty]
✖   type may not be empty [type-empty]

✖   found 2 problems, 0 warnings
ⓘ   Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint

10.3 cz-git 交互式提交

对于不熟悉规范的成员,可配置交互式提交工具,通过选择的方式生成规范的提交信息,零学习成本。

10.3.1 安装依赖

npm install -D cz-git commitizen

10.3.2 配置package.json

{
  "scripts": {
    "commit": "git-cz"
  },
  "config": {
    "commitizen": {
      "path": "node_modules/cz-git"
    }
  }
}

10.3.3 自定义配置(可选)

commitlint.config.js 中增加自定义提示配置,支持中文:

module.exports = {
  extends: ['@commitlint/config-conventional'],
  // 提示配置
  prompt: {
    // 中文提示
    messages: {
      type: '选择你要提交的类型 :',
      scope: '选择一个影响范围 (可选):',
      customScope: '输入自定义的影响范围:',
      subject: '简短描述本次变更:\n',
      body: '详细描述本次变更 (可选). 使用 "|" 换行:\n',
      breaking: '列出破坏性变更 (可选):\n',
      footerPrefixsSelect: '选择关联的Issue类型 (可选):',
      customFooterPrefixs: '输入自定义前缀:',
      confirmCommit: '确认提交以上信息?'
    },
    // 自定义类型选项
    types: [
      { value: 'feat', name: 'feat: 新增功能', emoji: '✨' },
      { value: 'fix', name: 'fix: 修复Bug', emoji: '🐛' },
      { value: 'docs', name: 'docs: 文档变更', emoji: '📝' },
      { value: 'style', name: 'style: 代码格式', emoji: '💄' },
      { value: 'refactor', name: 'refactor: 代码重构', emoji: '♻️' },
      { value: 'perf', name: 'perf: 性能优化', emoji: '⚡' },
      { value: 'test', name: 'test: 测试相关', emoji: '✅' },
      { value: 'chore', name: 'chore: 工程配置', emoji: '🔧' },
      { value: 'ci', name: 'ci: CI/CD', emoji: '🚀' },
      { value: 'revert', name: 'revert: 回滚提交', emoji: '⏪' }
    ],
    // 自定义scope选项
    scopes: [
      { name: 'user', description: '用户模块' },
      { name: 'order', description: '订单模块' },
      { name: 'goods', description: '商品模块' },
      { name: 'utils', description: '工具函数' },
      { name: 'components', description: '公共组件' }
    ],
    // 是否开启emoji
    useEmoji: true,
    // subject长度限制
    subjectLimit: 50
  },
  rules: {
    // ... 原有规则
  }
};

10.3.4 使用方式

代替 git commit 命令,执行:

npm run commit

然后按照提示一步步选择类型、范围、输入描述,自动生成符合规范的提交信息。

10.4 自动生成CHANGELOG与版本号

通过 standard-version 工具,基于规范的提交历史,自动计算语义化版本号、生成CHANGELOG文件。

10.4.1 安装

npm install -D standard-version

10.4.2 配置package.json脚本

{
  "scripts": {
    "release": "standard-version",
    "release:major": "standard-version --release-as major",
    "release:minor": "standard-version --release-as minor",
    "release:patch": "standard-version --release-as patch"
  }
}

10.4.3 使用

# 自动根据提交历史计算版本号,生成CHANGELOG,打tag
npm run release

# 手动指定升级主版本号
npm run release:major

执行后会自动:

  1. 读取提交历史,根据feat/fix/BREAKING CHANGE计算版本号
  2. 更新package.json中的version字段
  3. 生成CHANGELOG.md文件,记录每个版本的变更
  4. 自动提交变更并打上git tag

10.5 CI流水线校验

为了防止有人绕过本地钩子提交不规范的代码,建议在CI流水线中增加提交信息校验。 以GitHub Actions为例,在 .github/workflows/commitlint.yml 中配置:

name: Commitlint
on: [pull_request]

jobs:
  commitlint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: wagoid/commitlint-github-action@v5

这样提交信息不规范的PR会直接校验失败,无法合并。

11. 团队落地最佳实践

11.1 落地步骤

第一步:达成共识

  • 团队一起讨论规范,确认类型、scope、规则,达成一致意见
  • 说明规范的价值与好处,让大家理解为什么要做,而不是强行推行
  • 给出完整的文档、示例、速查表,降低学习成本

第二步:工具兜底

  • 先上自动化工具,husky + commitlint 强制校验,从技术上保证规范落地
  • 配置cz-git交互式提交,降低学习门槛,新人也能快速上手
  • 工具配置由专人维护,避免每个人都要搭环境

第三步:逐步推行

  • 不用一开始就100%严格,先保证格式正确,再逐步提升内容质量
  • 新功能、新模块优先遵守,历史代码逐步整改
  • 前1-2周安排专人review提交信息,及时纠正不规范写法

第四步:持续优化

  • 定期回顾提交规范的执行情况,收集团队反馈
  • 根据项目特点调整规则,比如增加自定义type、自定义scope
  • 不断优化工具链配置,提升开发体验

11.2 不同规模团队的适配

小型团队(3-5人)

  • 规则从简,核心保证type + subject规范,body不做强制要求
  • scope可以不用,项目小模块少,通过subject就能定位
  • 工具简单配置,强制校验基础格式
  • 重点是统一习惯,保持历史干净

中型团队(10-20人)

  • 完整推行规范,type、scope、subject、body、footer全量要求
  • 明确scope命名规范,对齐业务模块
  • 核心功能、复杂改动必须写正文
  • 配置完整工具链,强制校验 + 交互式提交
  • 代码评审时同步评审提交信息

大型团队/开源项目

  • 严格执行规范,提交信息作为PR准入条件
  • 详细的贡献者文档,说明提交规范
  • CI流水线强制校验,不规范的PR无法合并
  • 配备自动化发布流程,基于提交信息生成版本与CHANGELOG
  • 定期清理不规范的提交历史

11.3 与分支策略配合

Feature开发分支

  • 开发过程中可以频繁提交,允许WIP(工作进行中)类的临时提交
  • 不用每次都写得非常规范,保证开发效率
  • 提交粒度小,方便随时回退、保存进度

合并到公共分支前

  • 通过 git rebase -i 整理提交历史,把零散的提交合并成规范的、有意义的提交
  • 删掉WIP、临时提交、修复上一个提交的小bug这类无意义提交
  • 保证公共分支的每一个提交都是原子的、规范的、可追溯的
  • 推荐使用Squash Merge(压缩合并),把整个PR的所有提交压缩成一个规范的提交合入主干

主干分支

  • 主干分支(main/master)的提交历史必须100%符合规范
  • 每一个提交对应一个功能、一个修复、一个改动,清晰可追溯
  • 禁止直接向主干提交不规范的代码

11.4 代码评审要点

提交信息是代码评审的一部分,评审代码的同时也要评审提交信息:

  1. 格式是否规范:type、scope、subject是否符合要求
  2. 类型是否准确:有没有类型混用的情况
  3. 描述是否清晰:能不能一眼看懂改了什么
  4. 粒度是否合适:有没有一个提交混了多个不相关的改动
  5. 正文是否充分:复杂改动有没有说明背景、方案、影响
  6. 关联是否完整:有没有关联对应的Issue、任务

不规范的提交要求修改后再合并,逐步培养团队的规范意识。

11.5 新人引导

  1. 把提交规范加入新人入职文档,作为必看内容
  2. 提供速查表、模板、示例,方便新人查阅
  3. 配置交互式提交工具,降低新人上手门槛
  4. 导师带教期间,检查新人的提交信息,及时纠正
  5. 前几次提交允许不完美,逐步引导,不用一上来就卡死

12. 常见问题FAQ

Q1:一次提交包含多个类型的改动怎么办?

A:优先按核心改动确定type,比如主要是加功能,顺便改了格式,就用feat。 但更推荐拆分提交:把不同类型的改动拆成多个独立提交,比如格式调整单独一个style提交,功能改动单独一个feat提交。拆分后提交历史更清晰,也方便单独回滚。

Q2:已经提交了但还没推送,怎么修改提交信息?

A:如果是最近一次提交,执行 git commit --amend,进入编辑器修改提交信息,保存退出即可。 如果是历史提交,用交互式变基:git rebase -i <提交哈希>,把要修改的提交前的pick改成r,保存后依次修改每个提交的信息。

Q3:已经推送到远程的不规范提交怎么办?

A:如果是个人分支,没人基于你的分支开发,可以修改后强制推送:git push --force-with-lease。 如果是公共分支、已经有人合入了,不建议修改历史,会影响其他人的代码,后续提交注意规范即可。不要为了规范破坏协作。

Q4:WIP(开发中)的提交怎么写?

A:个人开发分支可以用 wip: xxx 作为临时提交,比如 wip: 用户中心开发中。 注意:WIP提交只能留在个人分支,合并到公共分支前必须清理掉,整理成规范的提交。 如果团队需要正式支持WIP类型,可以在commitlint配置的type-enum中增加wip。

Q5:修复上一个提交的小bug,怎么提交?

A:如果还没推送,建议直接用 git commit --amend 追加到上一个提交里,保持历史干净。 如果已经推送了,单独提交的话,用对应类型,比如fix,描述清楚修复的内容。不要写“修复上一个提交的bug”这种无意义描述。

Q6:中文还是英文?

A:根据团队情况选择,国内团队优先中文,保证所有人都能快速看懂。开源项目、国际化团队用英文。 核心是统一,不要一会儿中文一会儿英文,更不要中英文混杂在同一个subject里。

Q7:第三方依赖升级用什么类型?

A:普通的依赖版本升级,不影响业务功能,用 chore。 如果是大版本升级,有破坏性变更,或者为了支持新功能升级依赖,建议单独一个chore提交升级依赖,再一个feat提交开发新功能。 不要把依赖升级和业务代码改在同一个提交里。

Q8:删除废弃的代码/功能用什么类型?

A:如果是删除面向用户的功能、对外暴露的API,属于破坏性变更,用 feat!refactor!,标注BREAKING CHANGE。 如果是删除内部废弃代码、用户无感知的清理,用 refactorchore

Q9:数据库表结构变更用什么类型?

A:看变更目的:

  • 新增功能带来的表结构变更,随功能一起算 feat
  • 修复bug带来的表结构修正,算 fix
  • 优化查询性能的表结构调整,算 perf
  • 纯表结构重构,功能不变,算 refactor

建议数据库变更单独提交,方便追溯。

Q10:团队有人总是不遵守规范怎么办?

A:

  1. 先上工具:用husky + commitlint 强制拦截,不规范根本提交不了,从技术上解决问题,不用人工提醒
  2. 再讲价值:跟大家说明规范的好处,不是为了卡人,是为了提升所有人的效率
  3. 纳入评审:代码评审时同步检查提交信息,不规范的要求修改后再合并
  4. 以身作则:团队负责人、老员工带头遵守,做好榜样

Q11:规范太严格会不会影响开发效率?

A:不会。 写一个规范的提交信息只需要多花十几秒,但换来的是后续排查问题、代码评审、版本发布时节省的几小时甚至几天。 而且有交互式提交工具,几乎不用动脑子,跟着选就行,学习成本非常低。 短期看增加了一点工作量,长期看是大幅提升团队协作效率。

Q12:老项目历史提交都不规范,要不要全部改?

A:不建议改历史提交。 修改历史提交会影响所有协作者,有风险,而且收益不高。 正确的做法是:从现在开始,新的提交全部遵守规范,历史的不用管。随着时间推移,规范的提交会越来越多,历史慢慢就被覆盖了。

13. 其他

13.1 速查表

# 类型速查
feat: 新增功能        fix: 修复Bug
docs: 文档变更        style: 代码格式
refactor: 代码重构    perf: 性能优化
test: 测试相关        chore: 工程配置
ci: CI/CD流程         revert: 回滚提交

# 格式模板
type(scope): subject

body

footer

13.2 Git常用命令

查看完整Git命令 →

查看提交历史

# 简洁查看提交历史
git log --oneline

# 查看最近n条提交
git log -n 10 --oneline

# 按作者筛选
git log --author="张三" --oneline

# 按类型筛选(比如只看feat)
git log --grep="^feat" --oneline

修改提交信息

# 修改最近一次提交的信息
git commit --amend

# 交互式变基,修改历史提交
git rebase -i HEAD~5

回滚提交

# 回滚指定提交,生成新的回滚提交
git revert <提交哈>

# 重置到指定提交,保留改动(谨慎使用)
git reset --soft <提交哈>

13.3 参考链接

版本管理 git
Q-bot
hello!我是 Q-bot,我会唱、跳、rap,can i help you?