git-commit · git:20260929.7cde9db · 2026-09-29 · sha256 57585fe968eacf36
git-commit git:20260929.7cde9dbA
Immutable. This exact content never changes and is served at /api/v1/blob/57585fe968eacf36.
--- name: git-commit description: 使用约定式提交规范执行 git commit。当用户说「帮我提交」「提交一下这些改动」时使用。 license: MIT allowed-tools: Bash metadata: category: Git 与协作 tagline: "按约定式提交规范生成提交信息并提交" example: "帮我提交" --- # Git 约定式提交 ## 概述 使用约定式提交(Conventional Commits)规范创建标准化、语义化的 git commit。分析实际 diff 来确定合适的 type、scope 和消息。 ## 语言设置 **默认生成中文提交消息。** 用户可通过参数指定其他语言,例如: - 无参数 → 中文消息 - `--lang=en` → 英文消息 ## 约定式提交格式 ``` <type>[可选 scope]: <描述> [可选正文] [可选脚注] ``` ### 中文消息示例 ``` feat(auth): 引入 JWT 验证以保护接口安全 实现 JWT Token 验证中间件,解决接口未鉴权的安全风险: - 验证 Token 签名和过期时间,防止伪造请求 - 从 Payload 提取用户声明,供下游使用 - 将用户上下文注入请求对象,避免重复查询 - 处理 Refresh Token 轮换,保持会话连续性 ``` ### 英文消息示例 ``` feat(auth): add JWT validation to secure API endpoints ``` ## 提交类型 | 类型 | 用途 | | ---------- | ---------------------------- | | `feat` | 新功能 | | `fix` | 修复缺陷 | | `docs` | 仅文档变更 | | `style` | 代码格式/风格(不影响逻辑) | | `refactor` | 重构(非功能/非修复) | | `perf` | 性能优化 | | `test` | 新增/更新测试 | | `build` | 构建系统/依赖变更 | | `ci` | CI/配置变更 | | `chore` | 维护/杂项 | | `revert` | 回退提交 | ## 破坏性变更 ``` # type/scope 后加感叹号 feat!: 移除已废弃的接口以简化 API 维护 # BREAKING CHANGE 脚注 feat: 支持配置继承以减少重复配置 BREAKING CHANGE: `extends` 键的行为已变更 ``` ## 提交拆分策略 当检测到以下情况时,应建议拆分为多个提交: 1. **混合类型**:新功能 + 缺陷修复在同一提交中 2. **多关注点**:不相关的变更混在一起 3. **大范围变更**:跨越多个模块的修改 4. **文件模式混合**:源码 + 测试 + 文档混杂 5. **依赖混杂**:依赖更新与功能代码混合 命中任一条时,**在动手之前**给出拆分方案(分几个提交、各是什么 type),再按用户的 选择走。什么时候做这件事,见「工作流程」第 2 步。 > 这条有实测依据:模型能正确识别出「新接口 + bug 修复」,却因为用户说了「一起提交」 > 就把建议咽了回去,直接合成 `feat(...)` —— **识别出来 ≠ 说出口**。原先流程里写的是 > 「暂存区有内容 → **直接**生成提交消息」,那个「直接」正好跳过了这个判断。 ## 工作流程 ### 1. 分析差异 ```bash # 首先检查暂存区 git diff --staged # 同时检查状态,判断暂存区和工作区情况 git status --porcelain ``` **默认只提交暂存区(staged)的代码。** 流程如下: 1. 先检查暂存区是否有内容(`git diff --staged` 是否有输出) 2. **暂存区有内容** → **先过一遍「提交拆分策略」**:命中其中任一条(尤其是「混合类型」), **先给出拆分建议**,再按你的选择走。**你说了「一起提交」也要先建议** —— 你可能没意识到 改动混了,也可能就是要合并,那由你决定。确认不混 → 使用暂存区差异生成提交消息 3. **暂存区无内容** → 提示用户:"暂存区没有文件,是否要提交工作区的变更?" — 等待用户确认后再执行 ### 2. 暂存文件(如需要) 仅在用户确认提交工作区变更后,或需要按逻辑分组时暂存: ```bash # 暂存指定文件 git add path/to/file1 path/to/file2 # 按模式暂存 git add *.test.* git add src/components/* ``` **绝不能提交密钥文件**(.env、credentials.json、私钥等)。 这条**不因任何理由放宽**。下面三个借口都不成立: - 「里面只是占位值 / 测试用的」—— 该不该进版本控制由**文件的性质**决定,不由内容决定; 而且**一旦提交过,即使之后删掉,历史里仍然在** - 「用户明确要求了」—— 用户没有义务知道哪些文件不能提交,这正是这个技能存在的意义。 应当拒绝并说明理由,而不是照做 - 「就这一次」—— 历史是永久的,没有「这一次」 正确做法:把该文件加进 `.gitignore`、只提交其余改动,并**明确告诉用户为什么拒绝**, 以及他确实需要时该怎么办(用环境变量注入,或提交一份 `.env.example`)。 > 这条有实测依据:模型读到 `.env` 后自行判断「内容看着像占位值」,于是**照用户的 > 要求把它提交了**。判断标准一旦从「文件性质」滑到「内容像不像真的」,规则就失效了。 ### 3. 生成提交消息 分析 diff 来确定: - **Type**:这是什么类型的变更? - **Scope**:影响哪个区域/模块? - **描述**:一行概括**为什么要做这个变更**(现在时态、祈使语气、<72 字符),侧重动机而非动作本身 **描述应说明"为什么",而非仅仅"改了什么"。** 好的描述让读者理解变更的意图和背景,而不需要去看 diff。 示例对比: ``` # 不好 — 只说了做了什么 fix: 修改登录接口返回值 # 好 — 说明了为什么改 fix: 登录接口需返回用户角色以支持权限控制 ``` ``` # 不好 — 只说了做了什么 feat: 添加缓存模块 # 好 — 说明了为什么加 feat: 引入缓存层以降低数据库查询延迟 ``` ### 4. 执行提交 ```bash # 单行 git commit -m "<type>[scope]: <描述>" # 多行,含正文/脚注 git commit -m "$(cat <<'EOF' <type>[scope]: <描述> <可选正文> <可选脚注> EOF )" ``` ### 5. Push 规则 **默认不执行 `git push`。** 只有当用户明确说了"push"或"推送"时,才在提交后执行 push。 ## 最佳实践 - 一个提交只包含一个逻辑变更 - 使用现在时态:"添加" 而非 "添加了" - 使用祈使语气:"修复缺陷" 而非 "修复了缺陷" - 引用议题:`Closes #123`、`Refs #456` - 描述保持在 72 字符以内 ## Git 安全协议 - 禁止修改 git config - 未经用户明确要求,禁止执行破坏性命令(--force、hard reset) - 未经用户要求,禁止跳过钩子(--no-verify) - 禁止 force push 到 main/master - 如果提交因钩子失败,修复问题后创建新提交(不要 amend)