第 8 章:Git 集成
在前三章中,我们分别掌握了如何使用 Claude Code 进行对话理解、代码编辑、以及终端命令执行。这些能力加在一起,已经能覆盖大部分日常开发工作。但有一个环节始终绕不过去——提交代码。
传统 AI 编程工具对 Git 的支持通常停留在"帮你写个 commit message"的层面。Claude Code 的做法完全不同:它将 Git 状态感知内建到 Agent 的底层机制中,从感知变更、追踪差异、到执行完整的分支操作和 PR 工作流,形成了一套完整的版本控制集成。
本章目标:理解 Claude Code 的 Git 自动化能力边界,掌握从 commit message 生成到分支管理、PR 创建、冲突解决的完整工作流,建立安全使用 Git + AI 的最佳实践。
8.1 自动 Git 状态感知
不需要你告诉它——Claude 自己知道
当你打开 Claude Code 开始对话时,它自动知道以下信息:
- 当前在哪个分支
- 哪些文件被修改了(modified)
- 哪些文件已暂存(staged)
- 哪些文件未跟踪(untracked)
- 与远程分支的同步状态(ahead / behind)
你不需要运行 git status,也不需要把状态信息手动粘贴给 Claude——它在每次对话启动时就已经建立了这份认知。
这对 Claude 的行为意味着什么
Git 状态感知会直接影响 Claude Code 的决策和行为。举几个典型场景:
场景 1:修改前自动确认状态
用户:帮我把 utils/formatDate.ts 中的日期格式改成 ISO 8601
Claude 行动:
→ 先检查 git status(确认文件未被其他人修改,避免冲突)
→ 读取 utils/formatDate.ts
→ 执行修改
→ 完成后提示:"已修改 utils/formatDate.ts,其余 3 个文件也有未提交变更(src/api/users.ts、src/components/Header.vue、package.json),是否一并查看?"Claude 知道它改了一个文件,也知道你还有其他未提交的改动。这种全局意识让它能主动提醒潜在的关联风险。
场景 2:完成功能后主动建议提交
用户:功能做好了,跑一下测试
Claude:
→ 运行 pnpm test
→ 测试全部通过
→ "测试全部通过 ✓。本次修改涉及以下文件:
- src/services/auth.ts(新增 login/logout 方法)
- src/api/authRoutes.ts(新增 /login /logout 端点)
- tests/auth.test.ts(新增认证模块测试)
需要我帮你整理提交吗?"Claude 不是被动等待指令,而是基于 Git 状态主动提出合理的下一步建议。这背后是 Agent 对"开发 → 测试 → 提交"工作流的理解。
你不需要再执行的命令
有了 Claude Code 的 Git 感知,以下命令的执行频率大幅降低:
| 传统工作流(手动) | Claude Code 工作流 |
|---|---|
git status → 自己读 → 在脑中规划下一步 | Claude 自动读取并提示关键信息 |
git diff → 自己逐行审阅 | Claude 帮你解读 diff,提取关键变更 |
git log --oneline → 找上次提交的 hash | 问一句 "最近几次提交是什么" 即可 |
git stash → 切分支 → git stash pop | Claude 帮你规划操作顺序,减少手动步骤 |
这不是说你不应该再用这些命令——而是说你可以把精力从"执行 git 命令"转移到"做决策"上。Claude 负责查状态、展示信息、提出建议;你负责决定是否提交、以什么信息提交、是否合并。
8.2 让 Claude Code 写 Commit Message
最高频的 Git 场景
在所有 Git 相关的 AI 辅助中,"帮我写 commit message"可能是使用频率最高的功能。这并不是因为它最难——写一条 commit message 本身只需要一两分钟——而是因为它打断心流。写完一段代码后,你的思维还沉浸在实现逻辑中,此时被迫切换到"总结这次改了什么"的模式,是一种认知负担。
Claude Code 能无缝衔接这个过渡。
基本用法
最简单的触发方式:
帮我写个 commit message或者使用斜杠命令:
/commitClaude Code 收到指令后会执行以下步骤:
- 运行
git status查看变更文件列表 - 运行
git diff --staged(如果有暂存文件)和git diff(查看未暂存变更) - 分析 diff 内容:哪些是新增功能、哪些是修复、哪些是重构
- 结合项目的 commit 规范(如果 CLAUDE.md 中有定义)生成 commit message
- 将生成的 message 呈现给你审查
Claude 在看什么
Claude 在生成 commit message 时,考虑的要素远超"改了什么文件":
| 分析维度 | Claude 关注的内容 |
|---|---|
| 变更范围 | 哪些文件、哪些函数/类被修改 |
| 变更性质 | 新增功能 / 修复 bug / 重构 / 文档 / 配置 |
| 变更关联性 | 多个文件的改动是否属于同一个逻辑变更 |
| 项目上下文 | 从 CLAUDE.md 中读取的命名规范、commit 格式要求 |
| 历史风格 | 通过 git log 了解项目已有的 commit 风格 |
Commit Message 格式定制
如果你在 CLAUDE.md 或 .claude/settings.json 中定义了 commit 规范,Claude Code 会自动遵循。例如,CLAUDE.md 中的约定:
## Git Commit 规范
- git commit 信息使用中文
- 格式:<类型>: <简短描述>
- 类型:feat / fix / refactor / docs / chore / style / test
- 描述不超过 50 字,用句号结尾。有了这段约定,Claude 生成的 commit message 会类似:
feat: 新增用户认证模块的 login/logout API 端点。而不是英文的:
feat: add login/logout API endpoints for user authentication module实战演示
以下是一次完整的 commit 生成交互:
用户:帮我写个 commit message
Claude:
让我先查看当前的变更状态。
[执行 git status]
位于分支 feature/user-auth
要提交的变更:
修改:src/services/auth.ts
修改:src/api/authRoutes.ts
新文件:tests/auth.test.ts
[执行 git diff --staged]
变更分析:
1. auth.ts — 新增 login() 和 logout() 方法,使用 JWT 进行身份验证
2. authRoutes.ts — 新增 POST /login 和 POST /logout 端点
3. auth.test.ts — 新增 8 个测试用例,覆盖登录成功/失败/登出场景
建议的 commit message:
feat: 新增用户认证的登录与登出功能,包含 API 端点及单元测试。
- 实现 JWT 身份验证逻辑(auth.ts)
- 新增 POST /login 和 POST /logout 路由(authRoutes.ts)
- 添加 8 个认证模块测试用例(auth.test.ts)
是否使用这条 commit message 提交?注意 Claude 生成的是 Conventional Commits 风格——带类型的简洁标题 + 可选的要点补充。如果你偏好不同的格式(如 emoji commit、Angular 规范等),可以在 CLAUDE.md 中明确约定。
Commit 工作流:Claude 写 → 你审查 → 批准
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Claude 分析 │ ──→ │ 你审查 message │ ──→ │ 批准并提交 │
│ 变更并生成 │ │ 按需修改措辞 │ │ Claude 执行 │
│ message │ │ │ │ git commit │
└──────────────┘ └──────────────┘ └──────────────┘关键原则:commit message 的最终决定权在你手中。Claude 能看到 diff 但它看不到你的意图——有些变更的业务意义只有你清楚。审查时问自己:
- 这个描述准确反映了变更的目的吗?(不仅是什么,更是为什么)
- commit 的粒度合适吗?(是否应该拆成多个提交?)
- 如果六个月后回来看这条 message,我能理解这次变更的背景吗?
8.3 代码变更追踪
Claude 追踪的不只是最终结果
Claude Code 不仅能感知 Git 状态,它还会在对话过程中持续追踪代码变更的来源和演进。这种追踪分为两个维度:
维度一:Claude 自己的修改 vs 你的修改
在一个典型的协作会话中,你和 Claude 可能交替修改同一批文件。Claude Code 清楚地知道:
- 哪些改动是它做的(通过 Edit/Write 工具)
- 哪些改动是你手动做的(通过文件系统监控)
当你问 "上次那个改动是什么来着?" 时,Claude 不需要去翻 git log——它在对话上下文中已经记录了自己每一步操作的痕迹。
维度二:变更的演进过程
一个文件可能在同一轮对话中被多次修改。Claude 保留着每次修改的上下文,所以当你问:
这个函数怎么改成现在这样的?中间经历了什么?Claude 能够回溯:
- 第一次修改:提取重复逻辑为公共函数
- 第二次修改:根据你的反馈调整参数类型
- 第三次修改:修复边缘情况的 bug
在对话中查看 Diff
你不需要切到终端去跑 git diff——直接在对话中要求:
帮我看看当前有哪些改动,按文件汇总一下Claude 会执行 git diff 并将结果以结构化的方式呈现:
当前未提交的变更(工作区 vs HEAD):
📄 src/services/auth.ts (12 行变更)
+ login() 方法实现(新增 18 行)
- 旧的 authenticate() 调用(删除 6 行)
📄 src/api/authRoutes.ts (5 行变更)
+ POST /logout 路由定义(新增 5 行)
📄 package.json (1 行变更)
~ jsonwebtoken 依赖从 ^9.0.0 升级到 ^9.0.2这种结构化的呈现比终端的纯文本 git diff 更容易快速理解变更的全貌。
审查自己的变更
这是一个容易被忽视但非常有用的场景。写完一段代码后,让 Claude 帮你审查:
我刚改完了 src/services/payment.ts,帮我 review 一下改动,看看有没有遗漏或问题Claude 会:
- 通过
git diff看到你的所有改动 - 结合项目上下文(CLAUDE.md、相关文件)分析变更的合理性
- 指出潜在问题:未处理的错误路径、遗漏的边界条件、与现有代码的冲突
- 建议补充测试或用例
这相当于在提交前多做了一道自动化 review,而且审查者已经理解了项目的完整上下文。
8.4 分支操作
Claude Code 可以安全地管理你的分支
Claude Code 对分支操作的支持覆盖了日常开发的全部场景。从创建到切换、从合并到清理——你不需要记住具体的命令参数,只需要用自然语言描述意图。
但有一个重要前提: 以下操作的安全性取决于你的权限配置(见 8.7 节)。对于危险操作(如 force push、hard reset),强烈建议在配置中设置 deny 规则。
创建分支
创建一个 feature/payment-integration 分支Claude 会执行:
git checkout -b feature/payment-integration你也可以让 Claude 根据任务内容自动命名:
我要开始开发支付集成功能了,帮我建个合适的分支Claude 会根据项目的分支命名惯例(如果 CLAUDE.md 中有定义)生成一个合适的名称。
切换分支
切换到 main 分支Claude 会先检查当前分支是否有未提交的变更。如果有:
- 会提醒你先处理(提交、暂存、或放弃)
- 不会直接切换导致变更丢失
这比你自己 git checkout main 时突然被拒绝更友好——Claude 会提前发现问题并给出选项。
合并分支
把 feature/payment-integration 合并到 mainClaude 会执行以下安全检查流程:
1. 确认当前在目标分支(或自动切换)
2. git fetch origin(确保本地是最新的)
3. 检查两个分支之间是否有冲突
4. 如果有冲突 → 列出冲突文件,询问如何处理
5. 如果没有冲突 → 执行 merge(默认使用 --no-ff 保留分支历史)
6. 确认合并结果关键安全点: Claude 不会在未经你确认的情况下执行 git push。合并是本地操作,推送是远程操作——它们被明确区分。
删除分支
这个功能已经合并了,帮我删掉 feature/payment-integration 分支Claude 会先确认该分支确实已合并,然后执行:
git branch -d feature/payment-integration(使用 -d 而非 -D——如果分支未完全合并,Git 本身会拒绝删除并给出警告。)
暂存与恢复
正在一个分支上开发时,突然需要切到另一个分支处理紧急问题:
我需要在 feature/payment 分支上的工作先暂存一下,切换到 main 处理一个 hotfixClaude 会:
# 1. 暂存当前工作区的所有变更
git stash push -m "WIP: payment integration in progress"
# 2. 切换到 main
git checkout main
# 3. 创建 hotfix 分支
git checkout -b hotfix/critical-bug处理完 hotfix 后:
hotfix 搞定了,切回之前的工作Claude 会:
# 切回 feature 分支
git checkout feature/payment
# 恢复暂存的变更
git stash pop8.5 Git 工作流集成
完整的 Feature Branch 工作流
将 8.4 节的分支操作与 8.2 节的 commit 生成结合起来,就形成了一条完整的功能开发流水线。以下是一次典型的功能开发全流程:
阶段一:启动
─────────────────────────────
用户:我要开发用户通知功能,帮我从 main 创建 feature/user-notifications 分支
Claude:git checkout -b feature/user-notifications(已创建并切换)
阶段二:开发迭代
─────────────────────────────
用户:在 src/services/ 下创建 notificationService.ts,实现邮件通知发送
Claude:[创建文件、实现逻辑]
Claude:"已完成。测试通过。需要提交吗?"
用户:帮我写 commit message
Claude:feat: 新增邮件通知发送服务 notificationService.ts
Claude:[git add + git commit]
阶段三:继续开发
─────────────────────────────
用户:再加一个站内信通知功能
Claude:[修改文件、新增代码]
Claude:"站内信通知已实现。这次变更独立于邮件通知,建议单独提交。commit message 建议:feat: 新增站内信通知功能。是否提交?"
阶段四:推送与 PR
─────────────────────────────
用户:功能完成了,帮我推送到远程并创建 PR
Claude:git push -u origin feature/user-notifications
Claude:[通过 gh CLI 创建 PR,生成 PR 描述]
Claude:"PR 已创建:https://github.com/xxx/pull/42。描述中包含了功能说明、变更文件列表和测试情况。"创建 PR
如果你的环境中安装了 gh(GitHub CLI),Claude Code 可以直接帮你创建 PR:
帮我创建这个功能的 PRClaude 会:
- 推送当前分支到远程
- 运行
gh pr create生成 PR - 自动填写 PR 标题和描述(基于分支上的 commit 历史)
- 返回 PR 链接
生成的 PR 描述通常包含:
## 变更说明
新增用户通知功能,支持邮件和站内信两种通知方式。
## 变更文件
- src/services/notificationService.ts(新增,核心通知逻辑)
- src/services/emailProvider.ts(新增,邮件发送适配)
- src/api/notificationRoutes.ts(新增,通知 API 端点)
- tests/notification.test.ts(新增,23 个测试用例)
## 测试
- ✅ 23/23 单元测试通过
- ✅ 邮件发送集成测试通过
- ✅ 站内信实时推送测试通过
## 注意事项
- 需要在环境变量中配置 SMTP_* 邮件服务参数
- 站内信依赖 WebSocket,请确认网关配置即使没有 gh CLI,你也可以让 Claude 帮你生成 PR 描述文本,然后手动粘贴到 GitHub 网页上。
PR Review 准备
在提交 PR 之前,让 Claude 帮你做一轮自查:
Review 一下我当前分支上相对于 main 的所有改动Claude 会执行:
git diff main...feature/user-notifications然后从以下角度分析:
| Review 维度 | Claude 关注什么 |
|---|---|
| 逻辑正确性 | 是否有明显的逻辑错误、遗漏的边界条件 |
| 代码风格 | 是否与项目风格一致、是否有冗余代码 |
| 安全性 | 是否有 SQL 注入风险、XSS 漏洞、密钥硬编码等 |
| 性能 | 是否有 N+1 查询、不必要的循环、内存泄漏风险 |
| 可维护性 | 函数是否过长、是否有充分的注释、命名是否清晰 |
| 测试覆盖 | 核心逻辑是否有测试、边缘情况是否有覆盖 |
这不能替代人工 Code Review,但它能在同事审查之前帮你过滤掉大部分低级问题,让 Code Review 聚焦在架构和设计层面的讨论上。
冲突解决
合并冲突是 Git 工作流中最令人头疼的环节之一。Claude Code 可以显著降低解决冲突的心智负担:
feature/user-notifications 合并到 main 时有冲突,帮我解决Claude 的处理流程:
1. git merge main(触发冲突)
2. git diff --name-only --diff-filter=U(列出冲突文件)
3. 逐个读取冲突文件,分析冲突原因:
- 同一行被两边修改:两边各改了什么?
- 文件被删除 vs 被修改:哪边是正确的?
4. 提出解决方案:
- 保留两边的修改(合并)
- 选择其中一边(覆盖)
- 手动编写新的实现(重写)
5. 对每个冲突文件,询问你的决定后执行修复
6. git add 标记冲突已解决
7. git commit 完成合并关键原则: Claude 可以帮你定位冲突、分析冲突原因、提出解决方案——但解决冲突的决策权永远在你手中。不要让它自动选择"接受当前变更"或"接受传入变更",除非你完全理解两边的业务逻辑。
8.6 Git Hook 协同
Hooks 仍然生效——这是好事
Claude Code 在执行 Git 操作时,项目的 Git Hooks(.git/hooks/)依然会正常运行。这意味着:
- pre-commit hook 会在
git commit前运行(lint、格式化检查等) - commit-msg hook 会检查 Claude 生成的 commit message 是否符合规范
- pre-push hook 会在推送前运行(跑测试、安全检查等)
这不是限制,而是保护层。如果 Claude 生成的代码或 commit message 不合规范,hook 会拦截它,问题会立即暴露在对话中。
典型协同场景
场景:Lint 守卫
# .git/hooks/pre-commit
npm run lint-staged当 Claude 执行 git commit 时,如果它写的代码有 lint 错误,pre-commit hook 会阻止提交,错误信息会显示在对话中。Claude 会:
- 读取 lint 错误输出
- 自动修复问题
- 重新尝试提交
这形成了一个 "Claude 写代码 → hook 检查 → Claude 修复 → 通过后提交" 的自动化闭环。
场景:Commit Message 校验
# .git/hooks/commit-msg
# 检查 commit message 是否符合 Conventional Commits 格式
npx commitlint --edit $1如果 Claude 生成了一条不符合规范的 commit message,commitlint 会拦截。Claude 会读取错误信息,按照规范要求重新生成。
不建议做的事
用户:hook 太烦了,帮我跳过
Claude:git commit --no-verify不要让 Claude 使用 --no-verify 跳过 hooks。 Hooks 存在是有原因的——它们是你项目的质量护栏。如果某个 hook 确实有问题(比如检查太慢或规则过时),应该去修 hook 本身,而不是绕过它。
8.7 最佳实践
基于大量用户的实践经验,以下是 Git + Claude Code 组合使用中最重要的一组原则。
频繁提交:每次成功的 Claude 变更都是一个提交点
❌ 坏习惯:让 Claude 改 5 个文件 → 一次性全部提交
✅ 好习惯:每完成一个逻辑独立的变更 → 立即提交Claude Code 的每次操作都是可逆的——通过 Git。如果你保持着频繁提交的习惯,任何不满意的变更都可以精准回退到上一个状态点,不影响其他工作。如果一次提交了 5 个不相关的变更,回退就变成了"全部放弃"或"手动挑选"的困境。
推荐节奏:
Claude 完成一个功能点 → "帮我写 commit message" → 审查 → 提交
Claude 修复一个 bug → "帮我写 commit message" → 审查 → 提交
Claude 完成一次重构 → "帮我写 commit message" → 审查 → 提交审查 commit message:不要盲目接受
Claude 生成的 commit message 基于它能看到的 diff 和项目上下文。但它看不到的更多——你的商业理解、团队内部的术语约定、此次变更的深层动机。
审查时特别关注:
| 检查项 | 问题 |
|---|---|
| 描述准确性 | 它描述的是"做了什么"还是"为什么做"? |
| 粒度合适吗 | 是否一个 commit 里塞了太多不相关的内容? |
| 措辞一致吗 | 和项目已有的 commit message 风格一致吗? |
| 包含上下文吗 | 六个月的你自己能看懂这条 message 吗? |
分支隔离:Claude 的工作在自己的分支上
main (保护分支,你手动维护)
└── feature/user-notifications (Claude 工作区)
└── feature/payment-v2 (Claude 工作区)
└── refactor/cleanup-utils (Claude 工作区)- 每个任务一个分支:方便独立审查、独立回退、独立合并
- Claude 的变更不直接进入 main:永远通过 PR 或 merge 进入保护分支
- 分支命名清晰:
feature/xxx、fix/xxx、refactor/xxx——让 Claude 也能一目了然
diff 先行:提交前让 Claude 展示 diff
帮我看看将要提交的 diff,按文件汇总在确认 commit message 之前,先看一遍实际变更内容。这能发现以下问题:
- Claude 是否不小心修改了不该改的文件?
- 是否有自动格式化导致的无关变更混入?
- 是否有遗留的调试代码或注释?
一句话总结:永远让 Claude 先展示 git diff,再决定是否提交。 这不是不信任它——这是对你自己代码库的负责任态度。
配置 deny 规则:阻止危险 Git 操作
在 .claude/settings.json 或 ~/.claude/settings.json 中,明确禁止不可逆的危险操作:
{
"permissions": {
"deny": [
"Bash(git:push:--force:*)",
"Bash(git:push:-f:*)",
"Bash(git:reset:--hard:*)",
"Bash(git:clean:-fd:*)",
"Bash(git:branch:-D:*)"
]
}
}这些规则的意图:
| 规则 | 阻止的操作 | 为什么禁止 |
|---|---|---|
Bash(git:push:--force:*) | 强制推送到任意远程 | 覆盖远程历史,团队成员的工作丢失 |
Bash(git:reset:--hard:*) | 硬重置到任意提交 | 不可恢复地丢弃本地变更 |
Bash(git:clean:-fd:*) | 强制清理未跟踪文件 | 删除未被 Git 跟踪的文件 |
Bash(git:branch:-D:*) | 强制删除分支 | 即使未合并也会删除 |
这些操作并非不能用——而是不应该由 AI 自动执行。当你确实需要时,自己手动在终端中执行,这样你能完全控制时机和范围。
不要让 Claude 变基公共分支
❌ 危险:帮我把 feature/xxx rebase 到 main 并 force push
✅ 安全:帮我合并 main 的最新改动到 feature/xxx(merge,而非 rebase)git rebase 重写提交历史,配合 --force push 会让协作分支的提交记录混乱。对于公共分支或已经推送的分支,避免使用 rebase。
善用 CLAUDE.md 定义 Git 规范
在项目的 CLAUDE.md 中明确你的 Git 工作流约定,Claude Code 每次对话都会读取它:
## Git 规范
- commit message 使用中文,格式:`<类型>: <简短描述>`
- 类型:feat / fix / refactor / docs / chore / style / test / perf
- 分支命名:feature/<功能名>、fix/<问题名>、refactor/<模块名>
- 合并策略:始终使用 `git merge --no-ff` 保留分支历史
- 禁止 force push 到 main/master 分支
- 提交前确保 lint 和测试通过有了这段约定,Claude 在执行 Git 操作时会自动遵循这些规则,不需要每次手动提醒。
8.8 常见 Git 场景演练
本节提供四个最常见场景的完整演练。每个场景都展示了真实对话中的交互模式。
场景 1:完成功能后整理提交
场景描述: 你花了一个下午开发用户通知功能,中间经历了多次修改和调试。现在功能完成,但工作区有 7 个文件的变更,包含了一些调试代码和试验性更改。
对话演练:
用户:我刚完成了用户通知功能,改了好几个文件。帮我整理一下提交方案。
Claude:
让我先看一下当前的变更状态。
[执行 git status 和 git diff]
当前工作区有 7 个文件的变更:
📄 src/services/notificationService.ts — 通知发送核心逻辑(新增 120 行)
📄 src/services/emailProvider.ts — 邮件发送适配(新增 45 行)
📄 src/api/notificationRoutes.ts — 通知 API 端点(新增 30 行)
📄 tests/notification.test.ts — 测试用例(新增 200 行)
📄 src/utils/logger.ts — 加了一行调试日志(+1 行)
📄 .env.example — 新增 SMTP 配置模板(+5 行)
📄 src/components/Header.vue — 不小心加了个测试按钮(+3 行,应该撤销)
建议的提交方案:
方案一(推荐):拆分为 3 个提交
1. feat: 新增邮件通知发送服务及 API 端点
→ notificationService.ts + emailProvider.ts + notificationRoutes.ts
2. test: 新增通知模块的单元测试和集成测试
→ notification.test.ts
3. chore: 更新环境变量配置模板
→ .env.example
同时建议:
- 撤销 src/components/Header.vue 的测试按钮变更(git checkout)
- 撤销 src/utils/logger.ts 的调试日志(git checkout)
是否按此方案执行?要点: Claude 不仅整理了提交方案,还主动识别了不该提交的调试代码和测试按钮——这些是开发过程中的临时修改,不应该进入版本历史。
场景 2:在错误的分支上做了修改,迁移到正确分支
场景描述: 你在 main 分支上改了一堆代码,后来发现应该在 feature/xxx 分支上工作。
对话演练:
用户:糟糕,我一直在 main 分支上开发用户通知功能,已经改了很多。帮我安全地迁移到正确的分支。
Claude:
别担心,变更还没有提交,我们可以安全转移。让我确认一下状态。
[执行 git status]
确认:当前在 main 分支,7 个文件有未提交变更。
迁移方案:
1. git stash push -m "迁移:用户通知功能的工作变更"
→ 暂存 main 上的所有改动
2. git checkout -b feature/user-notifications
→ 创建并切换到正确分支
3. git stash pop
→ 将改动恢复到新分支
这三步是安全的——不会丢失任何改动,main 分支保持干净。
是否执行?要点: 这个场景的关键是在提交前发现问题。如果已经提交了,也可以让 Claude 用 git cherry-pick 或 git rebase 来迁移。但越早发现越好——stash 方案最安全也最简单。
场景 3:解决合并冲突
场景描述: 你正要把 feature/user-notifications 合并到 main,遇到了冲突。notificationService.ts 被两个分支同时修改。
对话演练:
用户:合并 feature/user-notifications 到 main,有冲突,帮我看看。
Claude:
[执行 git merge main]
检测到 1 个文件有冲突:src/services/notificationService.ts
[读取冲突文件,分析冲突标记]
冲突分析:
<<<<<<< HEAD (main 分支)
// main 分支上,sendNotification 使用旧的 sendEmail 函数
async sendNotification(user, message) {
await sendEmail(user.email, message);
}
=======
// feature 分支上,sendNotification 已重构为多通道
async sendNotification(user, message, channel = 'email') {
if (channel === 'email') {
await this.emailProvider.send(user.email, message);
} else if (channel === 'in-app') {
await this.inAppProvider.push(user.id, message);
}
}
>>>>>>> feature/user-notifications
建议解决方案:
feature 分支的实现是 main 的超集——它包含了 main 的功能(邮件发送)
并扩展了站内信通道。建议保留 feature 分支的完整实现。
具体操作:
1. 接受 feature 分支的 sendNotification 实现
2. 确认 sendEmail 的导入在 main 上是否已被移除(如已废弃)
3. 保留冲突解决后的文件,git add 标记已解决
4. git commit 完成合并
是否按此方案解决?要点: Claude 分析了冲突的原因(main 上用的是旧函数,feature 上已重构为多通道),给出了明确的建议方案,并说明了原因。它不只是机械地"接受传入"或"接受当前"——它在理解代码语义的基础上做判断。
场景 4:编写 PR Description
场景描述: 功能开发和提交都完成了,现在需要写一个高质量的 PR 描述给团队审查。
对话演练:
用户:帮我写个 PR description,这个功能支持多渠道通知(邮件 + 站内信)
Claude:
[执行 git log main..feature/user-notifications --oneline]
[执行 git diff main...feature/user-notifications --stat]
基于分支上的 4 个 commit 和变更内容,建议 PR 描述如下:
---
## 概述
新增多渠道用户通知功能,支持邮件通知和站内信通知两种方式。
## 变更内容
### 新增文件
- `src/services/notificationService.ts` — 通知服务核心,统一管理多渠道发送
- `src/services/emailProvider.ts` — 邮件发送提供者,封装 SMTP 连接
- `src/services/inAppProvider.ts` — 站内信推送提供者,基于 WebSocket
- `src/api/notificationRoutes.ts` — 通知 API 端点
- POST /api/notifications/send — 发送通知
- GET /api/notifications/history — 通知历史
### 修改文件
- `src/app.ts` — 注册通知路由
- `.env.example` — 新增 SMTP 和 WebSocket 配置模板
### 测试
- `tests/notification.test.ts` — 32 个测试用例
- 邮件发送成功/失败
- 站内信推送成功/失败
- 多渠道同时发送
- 通知历史查询
## 部署注意事项
- ⚠️ 需要在生产环境配置 `SMTP_HOST`、`SMTP_PORT`、`SMTP_USER`、`SMTP_PASS`
- ⚠️ WebSocket 网关需要支持站内信推送路由
- 不涉及数据库迁移
## 截图
(如有 UI 变更,建议附上截图)
---
是否使用此描述创建 PR?8.9 本章小结
本章覆盖了 Claude Code 中 Git 集成的完整能力边界。让我们回顾核心要点:
能力全景
Git 状态感知 ← ─ 基础层:Claude 自动感知分支、变更、同步状态
↓
Commit 生成 ← ─ 提效层:分析 diff,生成符合项目规范的 commit message
↓
分支操作 ← ─ 管理层:创建、切换、合并、暂存——全用自然语言控制
↓
工作流集成 ← ─ 协作层:PR 创建、Review 准备、冲突解决
↓
安全护栏 ← ─ 保护层:deny 规则阻止危险操作,hooks 自动校验质量核心原则回顾
- Claude 感知状态,你做决策——Claude 帮你查、帮你分析、帮你建议,但 commit、merge、push 的最终决定权在你
- 频繁提交,小步快跑——每完成一个逻辑变更就提交,让 Git 历史成为可精准回退的安全网
- 永远先看 diff 再提交——不要跳过审查步骤,Claude 也可能不小心改错文件
- 分支隔离 Claude 的工作——每个任务一个分支,Claude 的变更不直接进入保护分支
- 配置 deny 规则阻止危险操作——
force push、hard reset、git clean -fd等不可逆操作应被配置锁定 - 别跳过 Git Hooks——它们是质量护栏,不是障碍
Git + Claude Code 的协作哲学
Git 和 Claude Code 的关系不是"AI 替代版本控制"——恰恰相反,Git 是让 AI 编程变得安全可靠的基础设施。Claude 可以自动写代码、自动编辑文件,但只有 Git 给了你以下能力:
- 可逆性:任何 Claude 的变更都可以精准回退
- 可追溯性:每次变更都有记录,可以回溯到"谁在什么时候为什么改了这行"
- 可审查性:在 diff 视图中逐行审视 Claude 的输出
- 可协作性:你的工作和 Claude 的工作在同一套 Git 历史中,团队其他成员可以无缝参与
把 Git 用好,Claude Code 的能力边界就能安全地扩展;把 Git 用砸,AI 编程的效率提升可能被"改坏了不知道哪出问题"的风险所抵消。
下一步: 第 9 章将介绍模式切换——五种权限模式(Ask / Auto / Edit / Plan / Bypass)的深入对比,模型 Effort 等级的调节策略,以及如何根据任务复杂度选择正确的模式组合。这是"基础篇"的最后一章,掌握后你将具备独立完成日常开发任务的全部技能。