工作流程
按顺序执行以下步骤。如果任何步骤失败,请停止并向用户报告。
1. 评估工作树
运行 git status 和 git diff(包括已暂存和未暂存)来了解更改内容。如果没有更改,告知用户没有可提交的内容并停止。
2. 清理脏的子模块
如果 git status 显示子模块有“(已修改内容)”但没有暂存或预期的子模块指针更改,说明嵌套的子子模块发生了漂移(通常是由于递归的 --remote 更新)。对于每个这样的脏子模块,运行 git -C <子模块路径> submodule update --init 来恢复嵌套引用到父子模块所期望的提交。清理后,重新检查 git status 确认脏数据已消失。除非用户明确更改了子模块指针,否则不要暂存子模块指针更改。
3. 暂存所有内容,除非用户另有指定
如果用户没有指定特定文件,使用 git add -A 暂存所有更改(包括已跟踪和未跟踪的)。如果用户指定了特定文件或路径,则仅暂存这些文件。
4. 检查和自动修复
在提交之前,检测项目的 linter 并在暂存文件上运行自动修复。检测顺序:
- 首先检查项目级别的 lint 目标:如果 Makefile 有
lint或lint:fix目标,或者 package.json 有lint或lint:fix脚本,优先使用——这尊重项目自身的约定。只有在没有项目级别目标时,才进入按语言检测。 - Go(存在 go.mod):对暂存的 .go 文件运行
gofmt -w,然后运行go vet ./... - JavaScript/TypeScript(存在 package.json):如果存在 ESLint 配置,对暂存的 JS/TS 文件运行
npx eslint --fix。如果配置了 Prettier,还要对这些文件运行npx prettier --write。 - Python(存在 pyproject.toml、setup.py 或 requirements.txt):如果配置了 Ruff,对暂存的 .py 文件运行
ruff check --fix和ruff format。如果安装了 black,退回到 black。退回到 flake8(仅报告,无自动修复)。 - Rust(存在 Cargo.toml):运行
cargo fmt和cargo clippy --fix --allow-dirty - 未检测到 linter:跳过此步骤并继续。
自动修复后,使用 git add -u 重新暂存任何修改过的文件。如果 linter 报告了无法自动修复的错误,停止并向用户报告——不要在已知 lint 失败的情况下提交。
如果检测到 linter 但未安装二进制文件,警告用户并询问是否继续而不进行 lint 检查或中止。
5. 生成提交消息
分析暂存的差异以生成符合 Conventional Commit 规范的消息:
type(scope): short summary
Optional body with context on what changed and why.
规则:
- type:feat、fix、refactor、docs、test、chore、ci、perf、style、build 之一
- scope:可选但推荐——从主包、模块或目录派生。仅当更改涉及太多区域导致单个 scope 无意义时省略。
- 摘要行:小写、祈使语气、无句号、最多 72 个字符。
- 正文:仅在差异非平凡且摘要不足以给审阅者足够上下文时添加。保持简洁。
- 多个逻辑更改:选择最主要的作为 type/scope,在正文中提及次要更改。除非用户明确要求,否则不要拆分为多个提交。
- 破坏性更改:添加 BREAKING CHANGE 页脚或使用 ! 后缀(例如 feat!: ...)。
- 如果 linter 自动修复了文件,在正文中提及(例如“包含 gofmt 自动修复。”)。
6. 提交
使用生成的消息运行 git commit。对于仅摘要的消息使用 -m。对于带正文的消息,写入临时文件并使用 git commit -F 以保留换行符,然后清理临时文件。
7. 与远程同步
确定当前分支名称。然后:
- 如果分支有上游,运行
git push。 - 如果分支没有上游,运行
git push -u origin <branch-name>。 - 如果推送因远程领先而被拒绝,运行
git pull --rebase然后再次推送。如果变基产生冲突,停止并报告——不要自动解决合并冲突。
8. 确认
向用户报告:
- 提交哈希(短格式)
- 使用的提交消息
- 分支名称和远程同步状态
- 更改的文件、插入行数、删除行数(来自提交的
git diff --stat) - 运行的 linter(或未检测到)
边界情况
- 未配置远程:本地提交并告知用户。
- 分离头指针:提交前警告,建议先创建分支。
- 仅未跟踪文件:正常暂存并提交。
- 尊重 .gitignore——除非用户明确要求,否则绝不要强制添加被忽略的文件。