主题
06.3 Git 与 GitHub 工作流
让 Claude Code 自主完成从改动到 PR 的全链路,同时守住不可逆操作的边界。
读完你能做什么:把 git 操作安全地交给它,并接入 GitHub 的 PR 与审查流程。
一、Claude Code 的 git 能力全景
它通过 Bash 工具执行 git 命令,因此理论上能做任何 git 能做的事。关键是哪些该放开、哪些要守住。
| 操作类别 | 风险 | 建议 |
|---|---|---|
| 查询(status/diff/log/blame) | 无 | 直接 allow |
| 暂存与提交(add/commit) | 低 | allow,但审阅 commit message |
| 分支(branch/checkout/switch) | 低 | allow |
| 合并(merge/rebase) | 中 | 审阅,尤其 rebase |
| 推送(push) | 中 | ask |
| 强制操作(push --force/reset --hard) | 高 | deny 或严格 ask |
对应的权限配置:
json
{
"permissions": {
"allow": [
"Bash(git status)", "Bash(git diff *)", "Bash(git log *)",
"Bash(git add *)", "Bash(git commit *)",
"Bash(git branch *)", "Bash(git checkout *)", "Bash(git switch *)"
],
"ask": ["Bash(git push *)", "Bash(git merge *)", "Bash(git rebase *)"],
"deny": ["Bash(git push --force*)", "Bash(git reset --hard *)"]
}
}二、提交:让它写好 commit message
2.1 基本用法
text
> 把当前改动提交。commit message 遵循 conventional commits,
说清改了什么、为什么改。提交前先给我看 message。2.2 把规范写进 CLAUDE.md(一次配置,长期生效)
markdown
## Git 约定
- commit message 用 conventional commits:`type(scope): subject`
- type 取值:feat/fix/refactor/test/docs/chore
- subject 用祈使句,不超过 50 字符
- body 说明"为什么",不只是"做了什么"
- 不要在 message 里加"Generated by"之类的署名
- 一个 commit 只做一件逻辑上完整的事,不要把无关改动混在一起之后它每次提交都会遵守,无需重复说明。
2.3 拆分提交
text
> 我这次改了三件事:修了对账 bug、重命名了几个变量、更新了文档。
把它们拆成三个独立的 commit,每个 message 清晰。
先给我看你的拆分计划(哪些文件/改动归哪个 commit),我确认后再提交。三、分支与 PR 全流程
3.1 完整的功能开发流
text
<task>
实现"支持支付宝分账"功能,走完整的分支 → 开发 → PR 流程。
</task>
<workflow>
1. 从最新的 main 创建分支:feat/alipay-split
2. 实现功能(TDD:先测试后实现,见我们的约定)
3. 每个逻辑单元一个 commit
4. 推送分支
5. 创建 PR,PR 描述包含:
- 改动摘要
- 测试情况
- 需要 reviewer 特别注意的地方
6. 把 PR 链接给我
</workflow>
<constraints>
- push 前让我确认
- PR 用 draft 状态创建,我 review 后自己转正式
</constraints>3.2 接入 GitHub App
要让它能创建 PR、读 issue、回应评论,先装 GitHub App:
text
> /install-github-app它会引导你选仓库、配置集成(可选装 GitHub Actions)。
装好后:
text
> 看一下 issue #123,理解需求后实现它,完成后创建一个关联该 issue 的 PR四、审查工作流
Claude Code 有一组审查命令,能力和用途不同(详见 05.4 第三节):
4.1 提交前自查
text
> /code-review检查当前 diff 的正确性 bug 和可清理项。加 --fix 直接应用修复:
text
> /code-review --fix4.2 安全专项
text
> /security-review分析当前分支待提交改动的安全漏洞(注入、鉴权、数据泄露)。
4.3 审查一个 PR
text
> /review # 快速单次只读审查一个 GitHub PR
> /code-review medium 456 # 对 PR #456 做多代理深度审查4.4 让它响应 review 意见
text
> reviewer 在 PR #456 上留了几条评论,读一下,
对合理的意见做出修改,对你不认同的意见回复说明理由。
改完 push,并在 PR 上回应每一条评论。五、危险操作的防护
5.1 三条铁律
text
1. 不可逆操作(force push、hard reset、branch -D)必须人工确认
2. 涉及远程共享分支(main、develop)的操作必须人工确认
3. 删除类操作(clean -fd、reset --hard)默认 deny5.2 用 hook 做终极防线
即使权限规则有疏漏,hook 能提供额外拦截:
bash
#!/usr/bin/env bash
# .claude/hooks/guard-git.sh
# 拦截危险的 git 操作
CMD=$(jq -r '.tool_input.command // empty')
# 危险模式清单
DANGER='git push.*--force|git push.*-f |git reset --hard|git clean -[a-z]*f|git branch -D|git push.*:( |$)'
if echo "$CMD" | grep -qE "$DANGER"; then
jq -n --arg cmd "$CMD" '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "ask",
permissionDecisionReason: ("危险 git 操作,需人工确认:" + $cmd)
}
}'
exit 0
fi
exit 0json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{ "type": "command", "command": ".claude/hooks/guard-git.sh" }]
}
]
}
}5.3 用 worktree 隔离高风险实验
与其在主工作区冒险,不如在隔离的 worktree 里:
bash
claude -w risky-migration它会在 <repo>/.claude/worktrees/risky-migration 创建独立工作树。实验失败直接删掉,主分支毫发无损。见 06.7。
六、处理合并冲突
text
> 把 main 合并进当前分支,如果有冲突:
1. 逐个文件分析冲突,理解双方的意图
2. 对每个冲突,说明你打算怎么解决以及理由
3. 不确定的冲突(涉及业务逻辑取舍的)停下来问我
4. 解决后运行测试确认没破坏东西
不要盲目选择 "ours" 或 "theirs"。关键:冲突解决是最容易出错的场景,因为它涉及理解两边的意图。对涉及业务逻辑的冲突,一定要设人工确认点。
七、从 PR 恢复会话
Claude 创建的 PR 会自动关联会话。之后可以:
bash
claude --from-pr 456 # 打开筛选到该 PR 的会话选择器这让"改了一半的 PR"能精确续上,不用重新解释背景。
八、一份 git 工作流的 CLAUDE.md 片段
markdown
## Git 工作流
- 分支命名:`<type>/<short-desc>`,type ∈ feat/fix/refactor/chore
- 从最新 main 切分支,不在 main 上直接改
- commit 用 conventional commits,一个 commit 一件事
- push 前必须本地测试通过
- PR 用 draft 创建,描述含:摘要、测试情况、review 关注点
## 绝对禁止(这些操作必须人工执行)
- git push --force(任何形式)
- git reset --hard
- 直接 push 到 main/develop
- git clean -fd九、常见问题
| 症状 | 原因 | 对策 |
|---|---|---|
| 它想 force push | 变基后需要 | deny 掉,让你手动确认后执行 |
| commit 把无关改动混一起 | 没约束 | CLAUDE.md 写"一个 commit 一件事" |
| PR 描述太笼统 | 没给模板 | 在提示词/CLAUDE.md 给 PR 模板 |
| 它在 main 上直接改 | 没约束 | CLAUDE.md 写"不在 main 直接改" |
| 合并冲突乱解决 | 没设确认点 | 涉及业务逻辑的冲突必须问 |
| 提交署名带 AI 标记 | 默认行为 | CLAUDE.md 写"不加署名" |