# split-commit 将当前未提交改动拆分为多个原子提交。**不调用脚本**,严格按本文件执行,并与 `COMMIT_CONVENTION.md` 一致。 ## 0. 前置检查 ### 0.1 清理临时文件 若存在上次残留的 `msg.txt`,先删除: ```bash rm -f msg.txt ``` ### 0.2 读取规范(硬门槛) 执行前先读取并遵守 `COMMIT_CONVENTION.md`。若下列任一条件不满足,**不得提交**: - 提交头必须是 `(): ` 或 `: ` - `type` 必须在允许集合:`feat|fix|art|audio|scene|yarn|perf|refactor|style|docs|build|chore|test` - `scope` 仅在单一模块改动时填写;多模块/全局改动可省略 - `subject` 必须中文、动词开头、不超过 50 字、不加句号 - 一次提交只做一件事(One commit, one purpose) ## 1. 保护分支检查 检测当前是否在保护分支。保护分支列表按以下优先级获取: 1. 检查 `AGENTS.md`、`.cursor/rules/` 中是否有「保护分支」规则 2. 检查 `.git/config` 中 `branch.protected` 配置 3. 默认保护分支:`master`, `main`, `develop` - 若当前不在保护分支:直接进入第 2 节 - 若在保护分支,给出选项: - **[A]** 创建 feature 分支后继续拆分(推荐) - **[B]** 转移到新分支后压成单提交,不拆分 - **[C]** 取消 执行细则: - **A**:`git stash push --include-untracked` -> `git checkout -b ` -> `git stash pop` - **B**:同上切新分支后,仅一次 `git add -A` + 一次提交(使用 `msg.txt`) - **C**:停止,恢复原始状态 ## 2. 盘点变更 在仓库根执行: 1. `git status` - 确认整体状态 2. `git diff --stat` - 查看改动文件统计 3. `git diff` - 查看详细改动内容 4. `git diff --cached` - 查看已暂存的改动 目的:确认全部改动、识别 staged/unstaged、识别同文件多逻辑。 ## 3. 规则化分组(先分组,后提交) 按"意图一致"分组,不按文件数量分组。 ### 3.1 必须拆分触发条件 满足任一即必须拆: - 同一组改动可归属多个 `type` - 同一文件中包含多个独立目的(例如功能 + 重构) - 涉及多个核心 scope 且可独立提交 - 资源替换与代码逻辑混在同一组 ### 3.2 分组优先级 1. 先按变更目的区分:功能/修复/重构/测试/文档/资源 2. 再按模块 scope 细分:`blockpuzzle`、`dialog`、`scene-mgmt` 等 3. 同文件多逻辑必须标注 `git add -p` ### 3.3 最小拆分原则 避免过度拆分导致提交历史碎片化。以下情况**可以合并**: - 同一功能的多文件改动(如新增脚本 + 对应 Prefab) - 同一模块的多个 Bug 修复(如修复同一脚本的 3 个边界问题) ## 4. type/scope 决策规则 ### 4.1 type 选择顺序 1. 修复已有缺陷 -> `fix` 2. 新增或增强行为 -> `feat` 3. 纯美术资源替换 -> `art` 4. 纯音频资源替换 -> `audio` 5. 纯场景/Prefab 布局与参数调整 -> `scene` 6. 纯 Yarn 文本/分支脚本 -> `yarn` 7. 其余按规范:`perf|refactor|style|docs|build|chore|test` ### 4.2 scope 规则 - 单模块改动:使用对应 scope(如 `blockpuzzle`、`fix-system`、`timeline-kit`) - 跨模块或全局改动:省略 scope(如 `chore: ...`) ## 5. Unity 常见改动速查(type/scope 建议) | 改动类型 | 推荐 type | scope 选择 | | --- | --- | --- | | `Assets/Scripts/MiniGame/BlockPuzzle/` 逻辑修复 | `fix` | `blockpuzzle` | | `Assets/Scripts/MiniGame/BlockPuzzle/` 新交互/新规则 | `feat` | `blockpuzzle` | | 动画、贴图、模型、Spine 资源替换 | `art` | 对应系统 scope 或省略 | | 音效、BGM、FMOD 资源调整 | `audio` | `audio-kit` 或省略 | | `.unity` 灯光/后处理/镜头参数调整 | `scene` | 对应玩法 scope 或省略 | | Yarn 文本与分支改动 | `yarn` | `dialog` | | 仅测试代码改动 | `test` | 对应模块 scope | ## 6. 生成拆分方案并展示(必须含依据) 先产出表格,再等待用户确认。每一行必须包含: - 顺序 - 文件集合 - 变更目的 - `type/scope/subject` - 选择依据(为什么是这个 type/scope) - 暂存方式(`git add` 或 `git add -p`) 示例: | 顺序 | 文件 | 变更目的 | 提交头 | 依据 | 方式 | | --- | --- | --- | --- | --- | --- | | 1 | `Assets/Scripts/MiniGame/BlockPuzzle/Class/ShapeDragger.cs` | 修复拖拽边界判定 | `fix(blockpuzzle): 修复方块拖拽越界判定错误` | 已有行为修复,单模块 | `git add -p` | | 2 | `Assets/Prefabs/BlockPuzzle/*.prefab` | 调整拼图视觉资源 | `art(blockpuzzle): 更新方块拼图组件预制体表现` | 纯资源替换 | `git add` | ## 7. 提交消息校验(执行前最后守卫) 每组提交前逐条校验: 1. 格式:`(): ` 或 `: ` 2. `type` 在允许集合 3. `scope` 合法或省略合理 4. `subject` 中文、动词开头、<=50 字、无句号 5. body/footer 仅在需要时添加: - 需要解释原因/影响时加 body - 关联 issue 或破坏性变更时加 footer 任一不通过:先改消息,不执行 commit。 ## 8. 用户确认后执行 先询问:是否按该拆分执行?`[Y 执行 / n 取消 / 提出调整]` 用户确认后逐组执行: 1. 按方案 `git add` 或 `git add -p` 2. 复查本组暂存:`git diff --cached --stat` + `git diff --cached` 3. 使用 `msg.txt` 提交(见第 10 节) 4. 提交后检查工作区状态:`git status` ### 失败处理机制 - **若 `git add -p` 中用户跳过关键 hunk**:暂停执行,提示剩余改动如何处理 - **若提交失败(如 pre-commit hook 拒绝)**: - 显示失败原因 - 询问:[R] 重试 / [S] 跳过本组 / [A] 中止全部 - 若选择中止,确保工作区恢复到执行前状态 ## 9. 全部完成后的结果校验与回放 全部提交结束后必须输出: 1. `git log --oneline -`(N=本次新增提交数) 2. 回放清单(每条提交是否符合规范): - type 是否合法 - scope 是否合理 - subject 是否满足中文动词开头规则 3. 若发现不合规,明确说明并询问是否修正(`git commit --amend` 或 `git rebase -i`) ## 10. 中文提交消息写入方式(固定) PowerShell 5.1 下 `git commit -m "中文"` 可能乱码。统一使用: ```bash # 1. 在仓库根写 UTF-8 编码 msg.txt echo "feat(blockpuzzle): 添加方块旋转功能" > msg.txt # 2. 使用文件提交 git commit -F msg.txt # 3. 删除临时文件 rm -f msg.txt ``` ## 11. 关于 Pre-commit Hooks 若项目配置了 pre-commit hook(如 husky、lint-staged): - 每次提交都会触发 hook 检查 - 若 hook 执行较慢(如运行全量测试),拆分提交会变慢 - 如需跳过 hook(**不推荐,仅在紧急修复时**):`git commit -F msg.txt --no-verify` - **警告**:跳过 hook 可能引入未检查的问题,后续 CI 可能失败 ## 12. 工作目录 所有命令必须在仓库根执行。 ## 13. 快速参考:常见场景处理 ### 场景 A:同文件包含功能和重构 ```bash # 先提交功能改动 git add -p # 只选择功能相关的 hunk git commit -F msg.txt # feat: ... # 再提交重构 git add -p # 选择重构相关的 hunk git commit -F msg.txt # refactor: ... ``` ### 场景 B:误操作后的恢复 ```bash # 若某次提交后发现错误,撤销最后一次提交但保留改动 git reset --soft HEAD~1 # 然后重新分组提交 # 若需要完全放弃本次拆分的所有提交(谨慎使用) git reset --hard ORIG_HEAD ``` ### 场景 C:中途取消 ```bash # 若在第 8 步中途需要取消 git reset HEAD # 取消暂存 git checkout -- . # 恢复工作区(会丢失未提交改动,谨慎) rm -f msg.txt # 清理临时文件 ```