当前位置: 首页 > news >正文

【研发规范】Git 提交(commit)、CodeReview规范

本文将分为三个部分:

  1. 为什么需要提交规范?
  2. 提交规范详解(核心内容)
  3. 与 Code Review 流程的结合

1. 为什么需要提交规范?

在 Code Review 前,如果提交的代码杂乱无章,审查者会非常痛苦:

  • 理解成本高:审查者需要花费大量时间猜测这个提交到底做了什么为什么这么做
  • 范围不明确:一个提交里混杂了多个功能的修改,难以聚焦审查。
  • 历史追溯困难:混乱的提交信息使得日后排查问题、生成变更日志(Changelog)变得几乎不可能。

良好的提交规范旨在解决这些问题,它的核心目标是:让每一次提交都是一个逻辑独立、意图明确、易于理解的故事单元。


2. 提交规范详解

一份优秀的提交(Commit)主要由两部分组成:

  1. 提交信息
  2. 提交内容(代码变更集)

A. 提交信息规范

提交信息是写给未来维护者(包括你自己) 的说明文档。一个常见的规范格式是:

<类型>[可选 范围]: <主题>[空行][正文][空行][脚注]

举例说明:

feat(auth): add login with GitHub OAuth- Add new `GithubOAuthProvider` class implementing the OAuth flow.
- Extend `User` model to include `oauth_provider` and `oauth_id` fields.
- Add unit tests for the new provider.Closes #123
BREAKING CHANGE: The `User.login()` method now returns a Promise.

逐部分解析:

  1. 类型(Type): 说明本次提交的性质。常用类型包括:

    • feat: 新功能。
    • fix: 修复 bug。
    • docs: 仅文档更改。
    • style: 不影响代码逻辑的格式修改(如空格、分号)。
    • refactor: 既不是新功能也不是 bug 修复的代码重构。
    • perf: 性能优化。
    • test: 增加或修改测试用例。
    • chore: 构建过程或辅助工具的变动(如更新依赖)。
  2. 范围(Scope,可选): 说明本次提交影响的模块或组件。例如 (auth), (user-api), (ui-component)。这让审查者能快速定位受影响的核心区域。

  3. 主题(Subject): 对本次更改的简短描述

    • 规范:使用祈使句、现在时(如 "add", 而不是 "added" 或 "adds");首字母不需大写;结尾不加句号。
    • 长度:建议在50个字符以内。
  4. 正文(Body,可选): 详细说明做了什么为什么这么做,而不是怎么做的(代码本身展示了怎么做)。

    • 与之前的代码有何不同?
    • 为什么这个解决方案是合理的? (尤其是对于复杂的逻辑)
    • 是否有其他考虑过的方案?
    • 每行长度建议在72个字符以内。
  5. 脚注(Footer,可选): 用于存放元数据。

    • 关闭 IssueCloses #123, Fixes #456
    • 破坏性变更:如果本次提交是不兼容的变更,必须用 BREAKING CHANGE: 开头,并描述变更详情和迁移指南。

B. 提交内容规范

比提交信息更重要的是提交的内容本身。核心原则是:原子提交

  • 一个提交只做一件事

    • 正确示例:提交A只实现新功能,提交B只重构相关代码,提交C只修改文档。
    • 错误示例:一个提交里既修复了bug,又重构了代码,还顺手格式化了文件。
  • 为什么原子提交重要?

    • 易于审查:审查者可以轻松理解一个小的、逻辑完整的变更。
    • 易于回滚:如果某个功能引入问题,可以安全地回滚单个提交,而不会影响其他修改。
    • 易于定位问题:使用 git bisect 等工具时,原子提交能快速定位引入问题的具体变更。

3. 与 Code Review 流程的结合

提交规范是 Code Review 的前置条件。一个理想的流程如下:

场景:为购物车添加商品数量验证功能

步骤 1: 创建功能分支

git checkout -b feature/add-cart-quantity-validation

步骤 2: 进行原子开发与提交

  • 提交 1: 添加验证逻辑

    # 假设你修改了 shopping_cart.py
    git add shopping_cart.py
    git commit -m "feat(cart): add quantity validation for items- Validate that item quantity is a positive integer.
    - Throw `InvalidQuantityError` if validation fails.
    - Add relevant unit tests for valid and invalid cases."
    
  • 提交 2: 更新 API 文档

    # 假设你更新了 api_docs.md
    git add api_docs.md
    git commit -m "docs(api): update cart endpoint docs with quantity rulesDocument the new validation rule for the `quantity` field in the
    `POST /cart/items` endpoint."
    

步骤 3: 推送到远程并发起 Pull Request (PR) / Merge Request (MR)
此时,你的 PR 中将包含两个清晰、独立的提交。审查者可以:

  1. 快速浏览提交历史,了解工作内容。
  2. 分别审查每个提交,重点关注核心逻辑(第一个提交)和文档(第二个提交)。
  3. 如果发现文档有问题,可以直接评论在第二个提交上,而不会影响第一个提交的讨论。

步骤 4: 根据审查意见修改
审查者建议在验证逻辑中加入上限检查。

  • 不要直接提交,而是使用 git commit --amendgit rebase -i修正上一个相关的提交,保持历史整洁。
# 修改 shopping_cart.py 文件,添加上限检查
git add shopping_cart.py
git commit --amend # 这会将修改合并到 "feat(cart): add quantity validation..." 这个提交中
# 在打开的编辑器中,更新提交信息(如果需要的话):
# feat(cart): add quantity validation for items
#
# - Validate that item quantity is a positive integer between 1-99.
# - Throw `InvalidQuantityError` if validation fails.
# - Add relevant unit tests for valid and invalid cases.

步骤 5: 推送更新
由于修改了历史,需要强制推送(在功能分支上通常是安全的):

git push -f origin feature/add-cart-quantity-validation

PR/MR 会自动更新,审查者看到的是整理后最清晰的提交历史。

总结:优秀提交规范的核心价值

规范要点 对 Code Review 的好处 反面案例的坏处
清晰的提交信息 审查者秒懂提交意图,降低沟通成本。 fix a bug, 审查者需要猜是什么bug。
原子提交 审查小而精的代码块,思路不被打断,容易发现深层问题。 一个提交修改20个文件,混杂功能、修复、格式,审查如同大海捞针。
逻辑独立的变更集 可以按提交逐个审查、通过甚至回滚。 代码耦合严重,审查一个功能必须理解所有无关改动。

工具推荐

  • commitizen: 一个交互式工具,帮助你生成符合规范(如 Angular Convention)的提交信息。
  • husky + commitlint: 在 Git 提交时自动检查提交信息格式,确保规范被遵守。

遵循良好的提交规范,不仅是对审查者的尊重,更是对项目未来可维护性的投资,也是每一位专业工程师应具备的基本素养。

http://www.hskmm.com/?act=detail&tid=21343

相关文章:

  • PCIE 各个管脚的作用是什么?
  • Windows 11 局域网打印机共享设置
  • DailyPaper-2025-9-29
  • gpd winmax2 fedora42 睡眠秒唤醒问题
  • 国企人力资源管理系统怎么选?内行人推荐这8款,功能、服务双保障
  • spring service注入命名规则
  • 完整教程:基于岗课赛证的中职物联网专业“综合布线课程”教学解决方案
  • tensorflow加载和预处理信息
  • linux查询磁盘空间,查询指定目录的空间 df命令
  • 轻松规划房贷:用好公积金贷款,让梦想之家触手可及
  • milvus使用的etcd空间整理
  • 本土化战略赋能:Gitee如何领跑中国DevOps黄金赛道
  • 打印机错误0x0000709,问题排查和修复指南
  • k8s使用的etcd空间清理
  • MyBatis 与 JPA 的核心对比
  • 2025.9.29 测试
  • 深度学习(CVAE)
  • c# aot orm 框架测试 mysql
  • 洛谷题单指南-进阶数论-P2303 [SDOI2012] Longge 的问题
  • PK-2877电流互感器在高频脉冲电源模块测试中的应用方案
  • VC++ 使用OpenSSL创建RSA密钥PEM档案
  • CF1699D Almost Triple Deletions
  • QMT回测模式为什么要在副图进行
  • DSA:DeepSeek Sparse Attention
  • 荒野猎手出击!启明智显ZX7981PO:专治各种恶劣环境的5G插卡路由器
  • AWS CDK重构功能发布:安全重构基础设施即代码
  • 开发即时通社交软件APP首选系统,可定制开发,可提供源码
  • 死锁的处理策略-死锁的检测和解除
  • springboot3 mybatis 数据库操控入门与实战
  • 解决winform调用wpf窗体时原窗体缩小的问题