Git 与 PR 工作流
从改代码到发 PR 的完整链路交给 Claude Code。
Git 相关的操作是最适合让 Claude Code 全权代理的场景。原因很简单:它的动作模式是固定的(切分支、写代码、跑测试、提 commit、开 PR),错了也可回滚。学会把这条链路整个交出去,你每天能省下大量重复劳动。
这一节把整条链路拆成三个阶段,说明每一步让 Claude Code 做什么、它必须遵守哪些红线,最后给一个完整的会话示例。
三阶段:分支 → commit → PR
Claude Code 处理一个从零到 PR 的任务时,稳定的节奏是这样:
第一阶段:创建 feature 分支。 从 main(或者 develop)拉出一个语义清晰的分支名。命名遵循 feat/ fix/ refactor/ docs/ 前缀约定。这一步很多人喜欢自己敲 git checkout -b,但让 Claude Code 做的好处是它会顺手 git status 一下,确认工作区干净、没有未提交的旧改动混进新分支。
第二阶段:切分成多个原子 commit。 这是新手最容易做错的一环。要么攒一大堆改动最后一次性 commit,要么每改一行就 commit,都不理想。正确的粒度是:每完成一个可以独立通过测试的功能片段,就 commit 一次。 让 Claude Code 帮你判断这个粒度,比自己纠结要好得多。
第三阶段:gh pr create 起 PR。 走 GitHub CLI,让 Claude Code 生成 PR 标题、描述、测试计划。描述里必须包含变更摘要(why)和测试步骤(how to verify),这两块是 reviewer 最需要的信息。
具体让 Claude Code 做的事
在这条链路里,有几个动作特别适合交给 Claude Code,因为它做得又快又稳。
写 commit message
好的 commit message 讲的是“为什么改”,不是“改了什么”。前者靠脑子想,后者看 diff 就知道。Claude Code 会自己 git diff --cached 读改动,再结合会话上下文(你为什么改这里)合成一条 message。
你: 帮我把 staged 的改动 commit 了,遵循 Conventional Commits。
Claude Code: [git diff --cached] [git log -5]
读完之后建议这条 message:
fix(auth): 拒绝空字符串作为密码字段
用户提交空密码时后端应返回 400 而不是通过校验。
之前的校验只判断了 undefined,漏掉了空字符串这条路径。
我先跑 npm test,通过后就 commit,可以吗?建议
让 Claude Code 帮你写 commit message 时,一次让它 commit 一个粒度合适的片段,不要让它“把所有改动 commit 了”。前者是有判断的动作,后者是打包丢弃信息。
跑 lint 和 test
commit 之前,Claude Code 应该主动跑一遍项目的 lint 和 test。这不是它自作主张,而是最基本的守门。CLAUDE.md 里把这两条命令写清楚:
## 提交前必跑
- npm run lint
- npm test
lint 或 test 失败就停下来告诉我,不要硬提交。这样即使你偶尔忘了叮嘱,它也会自己跑。
生成 PR description 和 test plan
PR description 是给 reviewer 看的。Claude Code 会读整条分支的 commit history(git log main..HEAD),综合出一份摘要,然后附上 test plan 清单。
你: 帮我起 PR,base 是 main。
Claude Code: [git log main..HEAD] [git diff main...HEAD --stat]
我准备用这个描述发 PR:
## Summary
- 修复空密码通过后端校验的问题
- 补充了 auth service 的 3 条 unit test
- 更新 API 文档说明 400 响应格式
## Test plan
- [x] 本地跑 npm test 全绿
- [x] 手动 curl 空密码请求,返回 400
- [ ] Reviewer 检查 auth service 是否还有其他遗漏路径
标题:fix(auth): 空密码不再通过校验
要发吗?Claude Code 自己的红线
Claude Code 在 Git 场景下默认会拒绝一些危险操作,理解这些红线能省掉很多不必要的 back-and-forth。
不能碰的操作
- 不 amend 已推送到远端的 commit。 amend 会重写历史,如果别人已经 fetch 过这个分支,后续 rebase 会一团糟。只允许对本地未 push 的 commit 用 amend。
- 不 force push 到共享分支。 尤其是
main、develop、正在被审查的 PR 分支。force push 到自己独占的 feature 分支可以,但要说明理由。 - 不用
--no-verify绕过 pre-commit hook。 hook 是团队约定的守门员,绕过它等于把问题往后推。hook 挂了就修 hook,不是关 hook。 - 不在共享分支上
git reset --hard。 reset 掉的 commit 找回来很痛苦。回退用git revert,它会生成一个反向 commit,历史干净。
如果你确实需要这些操作(比如临时修一个错的本地 commit),要明确告诉 Claude Code“我知道后果,就在这个只有我在用的分支上做”,它才会照做。
一个完整的 session 示例
假设你刚写完一个“用户可以修改邮箱”的功能,现在要提 PR。整个过程可以短到只发一条指令。
你: 帮我把这个功能提 PR。base 是 main,PR 标题里带 feat 前缀。
Claude Code:
我先看一下当前状态。
[git status] [git branch --show-current] [git log main..HEAD]
现在在 main 分支上,有 4 个未 commit 的改动:
- src/services/user.ts(新增 updateEmail 方法)
- src/routes/user.ts(新增 PATCH /users/:id/email 路由)
- src/services/user.test.ts(3 条测试)
- CHANGELOG.md(新增一条)
我准备这样操作:
1. 创建分支 feat/user-update-email
2. 拆成 2 个 commit:service + route 一起,测试和 changelog 一起
3. 跑 npm test 和 npm run lint
4. push 之后 gh pr create
可以吗?
你: 可以。
Claude Code:
[git checkout -b feat/user-update-email]
[git add src/services/user.ts src/routes/user.ts]
[git commit -m "feat(user): 支持通过 PATCH 修改邮箱"]
[git add src/services/user.test.ts CHANGELOG.md]
[git commit -m "test(user): 补充 updateEmail 的测试和 changelog"]
[npm run lint] ✓
[npm test] ✓ 42 passed
[git push -u origin feat/user-update-email]
[gh pr create --title "feat(user): 支持修改邮箱" --body ...]
PR 已发:https://github.com/xxx/xxx/pull/128短短几轮对话,从 uncommitted 改动到 PR 上线。你在这个流程里唯一做的事,是确认它的计划。
想更省事
把这一整套流程写成 slash command 存在 .claude/commands/ship.md,之后一句 /ship 就自动跑一遍。写自定义命令的方法看 3.1 Slash 命令。
常见坑位与规避
在实际用起来之前,把下面这几个坑先记住,能少走弯路。
坑 1:让 Claude Code “把改动都 commit 了”。 它会打包成一个巨大的 commit,日后想拆开非常麻烦。正确姿势是告诉它“按逻辑分成几个 commit”,让它自己判断粒度并向你汇报计划。
坑 2:PR 描述写得太抽象。 如果它输出的 description 只有一句“实现了功能 X”,reviewer 看了一头雾水。要求它写出“改了什么、为什么这么改、怎么验证”,缺一不可。
坑 3:没让它看 base 分支的最新状态就直接开 PR。 有时候 main 已经往前走了几个 commit,你的分支基于旧 main 拉的,PR 里会带上一堆和你无关的 diff。开 PR 前让它 git fetch origin main,如果落后就先 rebase 或 merge。
坑 4:把 PR 的 test plan 写成“跑了 npm test”一句话。 test plan 是给 reviewer 看的验证步骤,不是你自己的 checklist。要写具体:怎么复现问题、改动后应该看到什么、有什么手动验证步骤。
什么时候你要自己插手
不是所有 Git 操作都适合让 Claude Code 全权做。下面这几种情况,你要自己上手:
- rebase 冲突解决。 Claude Code 可以辅助分析冲突原因,但接受哪一边、怎么合,要你自己判断。特别是涉及业务逻辑的冲突,模型不知道你团队的意图。
- 合并到 main 的最后按钮。 让人审的 PR 由人来 merge,不是 Claude Code 自动 merge。这是团队协作的礼节,也是最后一道防线。
- 敏感操作。 涉及 tag、release、submodule 变更,先自己想清楚再做。这些操作错了要连累很多人。
- 跨仓库的 PR。 一次改多个仓库并互相依赖时,顺序、时序都要人来协调。
学会这一节之后,你日常的 Git 动作能省掉 80%。剩下的 20%,正好是你该动脑的地方。