agentsclimarketplace

Git commit cn

Skill nanami7777777/git-commit-cn

Use this skill when writing git commit messages, splitting changes into commits, generating changelogs, or deciding version numbers. It enforces Conventional Commits with Chinese scopes, provides decision trees for type/scope/body selection, demonstrates how to analyze diffs and produce correct commit messages, and includes rules for multi-commit splitting, changelog generation, and semantic versioning. Triggers on git commit, git add, changelog, release, or version bump tasks.From its SKILL.md

Install
npx -y skills add nanami7777777/git-commit-cn

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

9.1 KB, ~3.0k tokens by cl100k_base, as published. Nobody here has run it

Git 提交信息规范

格式

<type>(<scope>): <subject>

<body>

<footer>

type 选择决策树

这次改动的效果是什么?
│
├── 用户能感知到新功能 → feat
├── 修复了用户能感知到的 bug → fix
├── 改了代码结构但行为不变 → refactor
├── 让某个操作变快了 → perf
├── 只改了测试代码 → test
├── 只改了文档/注释 → docs
├── 只改了代码格式(空格、分号、换行) → style
├── 改了构建配置/脚本/依赖版本 → chore
├── 改了 CI/CD 配置 → ci
└── 回滚了之前的提交 → revert

容易判断错的情况

改动错误 type正确 type原因
给已有接口加了参数校验featfix缺少校验是 bug,加上是修复
把 var 改成 constrefactorstyle没改逻辑,只是代码风格
升级 React 18 → 19chorefeat如果用了新特性就是 feat
加了错误日志featfix缺少日志导致排查困难,是修复可观测性
删除了废弃代码fixrefactor没修 bug,只是清理
加了 loading 状态stylefeat用户能感知到的 UI 变化是功能
把 any 改成具体类型refactorstyle没改运行时行为

scope 规则

用中文业务域,不用文件名或路径:

✓ feat(用户): 支持手机号一键登录
✓ fix(订单): 修复取消订单后库存未恢复
✓ refactor(支付): 统一微信和支付宝的回调处理
✗ feat(src/views/user): ...        ← 文件路径
✗ fix(UserService.ts): ...         ← 文件名
✗ feat(user-module): ...           ← 英文模块名

scope 选择规则

  1. 改动只涉及一个业务模块 → 用那个模块名
  2. 改动跨多个模块但有主次 → 用主要模块名
  3. 改动是基础设施(工具函数、配置、CI) → 省略 scope
  4. 改动是全局性的(升级框架、改构建配置) → 省略 scope

subject 规则

  • 中文,不超过 50 字符
  • 祈使语气:"添加"不是"添加了"
  • 描述效果,不描述实现
✓ feat(购物车): 支持批量删除商品
✓ fix(登录): 修复验证码 60 秒倒计时结束后按钮未恢复可点击状态
✗ fix(登录): 修复 bug
✗ feat: 更新代码
✗ chore: 改了点东西
✗ fix(登录): 在 LoginForm.vue 的 handleSendCode 方法中将 disabled 状态在 setTimeout 回调里重置为 false
                ↑ 这是实现细节,不是效果描述

body 决策

需要写 body 吗?
│
├── 破坏性变更(改了接口、改了数据结构) → 必须写
├── 修复了一个不明显的 bug → 必须写根因
├── 改动超过 100 行 → 建议写
├── 有多种方案,选了其中一种 → 建议写为什么
├── 简单的功能添加或小修复 → 不用写
└── style/docs/chore 类型 → 通常不用写

body 模板

修复 bug 时:

fix(订单): 修复并发下单时库存超卖

根因:多个请求同时读取库存值后各自扣减,最后写回的值覆盖了其他请求的扣减。
方案:改用 UPDATE ... SET stock = stock - 1 WHERE stock > 0 的原子操作。
放弃方案:
  - Redis 分布式锁:引入额外依赖,且有单点故障风险
  - 数据库悲观锁:并发量大时性能差

重构时:

refactor(支付): 统一微信和支付宝的支付回调处理

动机:两个支付渠道的回调处理逻辑 80% 相同,但分散在两个文件里,
每次改业务逻辑要改两处,容易遗漏。

做法:抽取 PaymentCallbackHandler 基类,渠道差异通过策略模式处理。
影响:WechatPayCallback 和 AlipayCallback 的公共逻辑移到了基类。

破坏性变更时:

feat(API): 用户列表接口改为分页返回

BREAKING CHANGE: GET /api/users 返回格式变更

之前:
  { "users": [...] }

现在:
  { "list": [...], "total": 100, "page": 1, "pageSize": 20 }

迁移方式:
  - 前端:将 response.users 改为 response.list
  - 需要传分页参数:?page=1&pageSize=20
  - 不传分页参数时默认返回前 20 条

从 diff 生成 commit message

当你看到一个 diff 需要生成 commit message 时,按这个流程:

步骤 1:扫描改动范围

  • 改了几个文件?
  • 改动集中在哪个业务模块?
  • 有没有不相关的改动混在一起?(如果有,应该拆成多个 commit)

步骤 2:判断 type

看改动的效果,不是看改了什么代码:

  • 加了新的 API endpoint → feat
  • 修了一个条件判断 → fix(如果修的是 bug)或 refactor(如果只是优化写法)
  • 加了 try-catch → fix(如果之前会崩溃)或 refactor(如果只是改善错误处理)

步骤 3:写 subject

从调用方/用户的角度描述:

  • 不要说"修改了 handleSubmit 函数" → 说"修复提交表单时的空指针错误"
  • 不要说"添加了 isValid 变量" → 说"添加表单提交前的数据校验"

示例

diff:

- const price = item.price * item.quantity
+ const price = Math.round(item.price * item.quantity * 100) / 100

commit: fix(订单): 修复商品金额计算的浮点精度丢失


diff:

+ import { rateLimit } from 'express-rate-limit'
+
+ app.use('/api/auth', rateLimit({
+   windowMs: 60 * 1000,
+   max: 5,
+   message: { code: 429, message: '请求太频繁,请稍后再试' }
+ }))

commit: feat(认证): 登录接口添加频率限制(每分钟 5 次)


diff:

- async function getUser(id) {
-   const user = await db.query('SELECT * FROM users WHERE id = ' + id)
+ async function getUser(id: string) {
+   const user = await db.query('SELECT * FROM users WHERE id = $1', [id])

commit:

fix(用户): 修复用户查询的 SQL 注入漏洞

根因:直接拼接用户输入到 SQL 语句中。
方案:改用参数化查询。

diff(多文件,跨模块):

# package.json
- "vue": "^3.3.0"
+ "vue": "^3.5.0"

# src/components/UserList.vue
- <script setup>
+ <script setup lang="ts">

# vite.config.ts
+ vue({ features: { propsDestructure: true } })

commit: chore: 升级 Vue 3.5 并启用 props 解构特性

(跨多个文件但都是同一件事:升级 Vue,所以是一个 commit)

什么时候拆成多个 commit

这些改动是同一件事吗?
│
├── 是 → 一个 commit
│   例:修一个 bug 改了 3 个文件 → 一个 fix commit
│
└── 不是 → 拆成多个 commit
    例:修了一个 bug + 顺手改了代码格式 → 一个 fix + 一个 style
    例:加了新功能 + 补了测试 → 一个 feat + 一个 test(或合并为一个 feat)

拆分原则

  • 每个 commit 应该能独立通过 CI(不能拆出一个编译不过的 commit)
  • 修 bug 和加功能不要混在一个 commit
  • 重构和功能变更不要混在一个 commit
  • 如果不确定要不要拆,问自己:回滚这个 commit 时,会不会误伤其他改动?

Changelog 生成规则

从 commit history 生成 changelog 时:

  • feat → 放在 "✨ 新功能" 下
  • fix → 放在 "🐛 修复" 下
  • perf → 放在 "⚡ 性能优化" 下
  • BREAKING CHANGE → 放在 "💥 破坏性变更" 下(最顶部,红色警告)
  • docs/style/chore/ci/test → 不出现在面向用户的 changelog 中
# v1.2.0 (2025-03-28)

## 💥 破坏性变更
- **API**: 用户列表接口改为分页返回 (#45)

## ✨ 新功能
- **用户**: 支持手机号一键登录 (#38)
- **购物车**: 支持批量删除商品 (#41)

## 🐛 修复
- **订单**: 修复并发下单时库存超卖 (#39)
- **登录**: 修复验证码倒计时结束后按钮未恢复 (#40)

## ⚡ 性能优化
- **列表**: 虚拟滚动优化长列表渲染 (#42)

版本号决策

有 BREAKING CHANGE 吗?
├── 是 → 主版本号 +1(1.x.x → 2.0.0)
└── 否 → 有 feat 吗?
    ├── 是 → 次版本号 +1(1.1.x → 1.2.0)
    └── 否 → 修订号 +1(1.1.1 → 1.1.2)

注意:0.x.x 阶段(未正式发布)可以在次版本号上做破坏性变更。

不要做的事

  • 不要一个 commit 混多种不相关改动
  • 不要 git add . 然后盲目提交,先 git diff --staged 看一眼
  • 不要提交 .env 文件或任何密钥
  • 不要提交 console.log 调试代码
  • 不要写"修复 bug"、"更新代码"、"改了点东西"
  • 不要用英文写完再机翻成中文
  • 不要在 subject 里写实现细节(文件名、函数名、变量名)

What ships with it: 2 files

2.7 KB alongside SKILL.md

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.