用 commit.md 和 create-pull-request.md 两个 Prompt 模板规范 Git 操作,将 209 个垃圾提交重构为清晰的 commit 历史,质量可累积。
我以前提交 PR 时,动辄几十个、有时甚至上百个 commit。绝大多数 commit 信息都是垃圾:Cleanup.、More tests.、fix.、some initial notes。
两个小小的 Markdown prompt 文件消除了这种摩擦:
commit.md 暂存你要提交的改动,读取暂存区的 diff,然后生成一条简短且有描述性的 commit 信息。
create-pull-request.md 读取 commit 日志,生成 PR 标题和描述,推送分支,然后执行 gh pr create。
有价值的部分在于质量是如何叠加的。好的 commit 信息会变成好的 PR 描述。这些描述给 reviewer 更好的上下文,而 commit 历史对后续的人类和 coding agent 都变得有用。
prompt 内容是 agent 无关的。我通常把这些 prompt 打包成命令(commands),不过 skills 也可以。对于这类日常维护任务,我同样倾向于选择快速、便宜的模型,而不是最贵的推理模型。
如果你偏好视频演示,可以看这里:
这不是假设的例子。我确实有一个包含 209 条 commits 的 PR,很多消息长这样:
Cleanup.
More tests.
Some initial notes.
More readme.
fix.
当然,你可以在合并前做 squash。但这并不能让分支历史在工作进行中变得有用,而且一个模糊的 squashed commit 仍然是模糊的。
通常没人会去看 commit 信息,直到生产环境着火、你试图弄清楚三个月前发生了什么。到那时历史变成了一个搜索索引,好的历史要好搜索得多。当然,LLM 可能会找到答案,但会花更长时间,浏览更多 diff,而且很可能烧掉更多 token。
我可以手工写一条好的 commit 信息。问题在于在频繁 commit、切换分支、或同时与多个 agent 协作时保持一致性——这些 agent 产生了一堆代码需要我审查和提交。这是一个好的 LLM 任务:阅读碰巧是代码的文本,总结它,然后执行几个 Git 命令,所以添加 prompt 来自动化这件事是合乎逻辑的下一步。
我现在的 commit.md 有意做得很小:
# Follow this instruction to commit changes.
Only use this instruction if the user asks for it.
* All commands should be run from a repo root.
* You will be given a list of files to commit.
* Commit all updated files if not otherwise specified. In this case use `git add .` from a repo root as a first step to stage all updated files.
* If user requested to commit specific files, use `git add <file1> <file2> ...` to stage specific files only.
* When committing, make sure to provide a sensible message. Figure out the message from chat history and/or the actual code changes. Make the message short and descriptive.
* Always run `git diff --staged` before composing the message so you can summarise what was changed.
* If you still lack context after reviewing the diff, consult the chat history; the diff should be your primary source for message content, not just `git status`.
Do NOT do any other verification or actions unrelated to this instruction. You SHOULD just commit the changes as specified here.
暂存区的 diff 是主要来源,因为它才是你真正要提交的东西。聊天历史作为额外上下文有用,但它可能不完整、过时,或者描述从未进入 worktree 的改动。
最后一行也很重要。没有这个边界,一个乐于助人的 agent 可能会运行 lint、开始修复无关的问题,或者把一个五秒钟的检查点变成一个大得多的任务。这个 prompt 只有一个职责。它不会替代你在宣布实际 coding 任务完成前运行的那些验证。
如果我想提交整个 worktree,git add . 很方便。如果我想提交一组特定的改动,我会给 agent 文件列表,不过我觉得这样做的时候不多。
配套的 create-pull-request.md 使用分支历史作为输入:
# Instruction to create pull request
This is an instruction to follow when user is referencing it. Only use this instruction when explicitly requested by the user.
1. Review the commit history between the base branch (use **main** unless another base is specified) and the current branch:
```bash
# Make sure remote is up to date
git fetch origin
# Get the current branch; use it when pushing and creating the PR
git branch --show-current
# Read commits on this branch that are not on the base branch
git log origin/<base branch>..HEAD --oneline | cat
* Short change description 1
* Short change description 2
* ...
git push origin <current branch> --set-upstream
gh pr create \
--title "<PR title>" \
--body-file - \
--base "<base branch>" \
--head "<current branch>" <<'EOF'
<PR description>
EOF
在比较之前需要执行 `git fetch origin`。否则 agent 可能会基于过时的远程状态总结错误的范围。
## 好的总结会叠加
第一个 prompt 本身就有用,但第二个 prompt 才是工作流开始回报的地方。
cleanup fix more changes update tests final tweaks
我得到的历史更接近这样:
Add AccountsStore load/validate/query and tests Add cmd/bbmd Cobra scaffold and DI smoke tests Implement bbmd auth sub-commands Implement bbmd pr sub-commands bbmd: unify auth/PR execution via exec helpers and tests
现在 PR 描述已经是已经很好的总结的汇总了。一个用这个工作流创建的真实 PR 有特定的标题、简短的变更说明,以及对 reviewer 有用的高层次列表。
同样的历史在后续也很有帮助:当队友审查 PR 时、当 agent 需要理解为什么某件事发生变化时、或者当你需要生成 release notes 时。叠加效应反方向也一样:模糊的 commits 给 PR prompt 模糊的输入。
对于 `commit.md`,我通常这样用:
当我想要检查点我的工作时手动运行它,例如用 `/commit` 或 follow `@commit.md`。最近我这样做得少了。
在我的长时间运行的 orchestration 循环中让 agent 运行它,通常作为由专用 sub-agent 处理的验证步骤的一部分。
`create-pull-request.md` prompt 的用法一样:我自己运行它,或者当要提交 PR 时让 agent 运行它。
## 如果出了问题
如果你注意到模型在这些 prompt 下行为异常,Agent Diagnostics Mode 可以帮助你理解原因。我通常用它来排查 prompt 问题,不仅仅用于 commit 和 PR 自动化。
也许吧。但这是好的那种偷懒。
输出更好,摩擦更低,历史更有用。我接受这个权衡。