Codex 自动写 Commit 够安全吗?一套证据化 Git 提交流程

让 Codex 根据 diff 生成 Commit 说明很容易,难的是保证它没有把用户的其他修改、临时文件或敏感配置一起提交。
我的边界是:AI 可以自动分析、检查、测试和生成说明;但提交对象必须由证据定义,最终 Commit 仍需要针对当前暂存快照的明确授权。
1. 先区分工作区、任务范围和暂存区
提交说明准确,不等于提交范围正确。准备 Commit 时需要回答:
- 工作区有哪些变化;
- 当前任务允许包含哪些变化;
- 暂存区实际包含哪些变化。
先读取事实:
bash
git status --short
git diff --name-status
git diff --stat
再按明确路径暂存:
bash
git add -- src/orders/service.py tests/test_order_service.py
不要把 git add . 当成 AI 的默认动作。
2. 四道门禁

范围审计
把本次任务允许的文件做成白名单。文件中混有用户修改时,继续缩小到 hunk,无法安全拆分就停止。
敏感检查
检查即将提交的真实快照:
bash
git diff --cached --name-status
git diff --cached --check
git diff --cached
重点排查 .env、密钥、数据库快照、日志、客户数据、绝对路径和无关删除。
聚焦测试
测试证据要包含命令、退出码和对应内容:
bash
python -m pytest tests/test_order_service.py -q
python -m ruff check src/orders/service.py tests/test_order_service.py
测试后又改了文件,旧结果不能继续证明新内容。
人工确认
确认前一次性展示分支、暂存清单、差异统计、测试结果、提交说明,以及剩余未暂存文件。暂存快照变化后,旧确认失效。
3. AI 生成说明必须基于 staged diff
候选提交说明应该来自 git diff --cached:
text
fix: 为订单创建增加幂等保护
- 以业务请求键查询既有订单,避免网络重试产生重复记录
- 在事务内记录请求键与订单映射
- 补充重复请求与并发请求测试
验证:python -m pytest tests/test_order_service.py -q
聊天上下文只能说明"打算做什么",暂存差异才说明"将要提交什么"。
4. Hook 是机械守卫,不是范围判断器
Git 的 pre-commit 可以运行检查并拒绝提交,commit-msg 可以校验提交说明格式。
Hook 很适合格式化、静态检查、敏感模式扫描和规范校验,但它不知道某个合法文件是否属于用户的另一项工作。因此 Hook 不能替代任务范围审计。
5. 提交后必须回读

提交完成后重新读取真实对象:
bash
git show --stat --oneline HEAD
git show --name-status --format=fuller HEAD
git status --short
检查 HEAD、作者、说明和文件清单是否正确,并确认用户的其他修改仍然保留。
6. 用检查点绑定证据
可以把提交准备过程保存为检查点:
json
{
"branch": "feature/order-idempotency",
"allowed_paths": ["src/orders/service.py", "tests/test_order_service.py"],
"staged_tree": "<sha256>",
"tests": [{"command": "python -m pytest tests/test_order_service.py -q", "exit_code": 0}],
"approved": false
}
AI 可以更新事实,但不能自己把 approved 改成 true。中断恢复时先重新计算暂存快照,哈希不同就让旧授权失效。
7. 自动化边界
适合自动化:读取差异、建议文件范围、运行检查、生成说明、提交后回读。
不应默认自动化:git add .、纳入未知修改、跳过失败测试、未经授权提交,以及自动 Push、合并、打 Tag 或发布版本。
总结
Codex 自动写 Commit 说明没有问题,危险的是让它默认拥有整个工作区。
更稳妥的方式,是把工作区事实、暂存清单、测试证据、提交对象和回读验证串成闭环;让 Hook 拦截机械错误,让人对最终暂存快照做一次明确确认。
当一条 Commit 能证明"为什么改、改了什么、怎么验证、没有卷入什么",AI 才真正提升了 Git 工作流。