Skip to content
Published at:

第 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 popClaude 帮你规划操作顺序,减少手动步骤

这不是说你不应该再用这些命令——而是说你可以把精力从"执行 git 命令"转移到"做决策"上。Claude 负责查状态、展示信息、提出建议;你负责决定是否提交、以什么信息提交、是否合并。

8.2 让 Claude Code 写 Commit Message

最高频的 Git 场景

在所有 Git 相关的 AI 辅助中,"帮我写 commit message"可能是使用频率最高的功能。这并不是因为它最难——写一条 commit message 本身只需要一两分钟——而是因为它打断心流。写完一段代码后,你的思维还沉浸在实现逻辑中,此时被迫切换到"总结这次改了什么"的模式,是一种认知负担。

Claude Code 能无缝衔接这个过渡。

基本用法

最简单的触发方式:

帮我写个 commit message

或者使用斜杠命令:

/commit

Claude Code 收到指令后会执行以下步骤:

  1. 运行 git status 查看变更文件列表
  2. 运行 git diff --staged(如果有暂存文件)和 git diff(查看未暂存变更)
  3. 分析 diff 内容:哪些是新增功能、哪些是修复、哪些是重构
  4. 结合项目的 commit 规范(如果 CLAUDE.md 中有定义)生成 commit message
  5. 将生成的 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 中的约定:

markdown
## 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 能够回溯:

  1. 第一次修改:提取重复逻辑为公共函数
  2. 第二次修改:根据你的反馈调整参数类型
  3. 第三次修改:修复边缘情况的 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 会:

  1. 通过 git diff 看到你的所有改动
  2. 结合项目上下文(CLAUDE.md、相关文件)分析变更的合理性
  3. 指出潜在问题:未处理的错误路径、遗漏的边界条件、与现有代码的冲突
  4. 建议补充测试或用例

这相当于在提交前多做了一道自动化 review,而且审查者已经理解了项目的完整上下文。

8.4 分支操作

Claude Code 可以安全地管理你的分支

Claude Code 对分支操作的支持覆盖了日常开发的全部场景。从创建到切换、从合并到清理——你不需要记住具体的命令参数,只需要用自然语言描述意图。

但有一个重要前提: 以下操作的安全性取决于你的权限配置(见 8.7 节)。对于危险操作(如 force push、hard reset),强烈建议在配置中设置 deny 规则。

创建分支

创建一个 feature/payment-integration 分支

Claude 会执行:

bash
git checkout -b feature/payment-integration

你也可以让 Claude 根据任务内容自动命名:

我要开始开发支付集成功能了,帮我建个合适的分支

Claude 会根据项目的分支命名惯例(如果 CLAUDE.md 中有定义)生成一个合适的名称。

切换分支

切换到 main 分支

Claude 会先检查当前分支是否有未提交的变更。如果有:

  • 会提醒你先处理(提交、暂存、或放弃)
  • 不会直接切换导致变更丢失

这比你自己 git checkout main 时突然被拒绝更友好——Claude 会提前发现问题并给出选项。

合并分支

把 feature/payment-integration 合并到 main

Claude 会执行以下安全检查流程:

1. 确认当前在目标分支(或自动切换)
2. git fetch origin(确保本地是最新的)
3. 检查两个分支之间是否有冲突
4. 如果有冲突 → 列出冲突文件,询问如何处理
5. 如果没有冲突 → 执行 merge(默认使用 --no-ff 保留分支历史)
6. 确认合并结果

关键安全点: Claude 不会在未经你确认的情况下执行 git push。合并是本地操作,推送是远程操作——它们被明确区分。

删除分支

这个功能已经合并了,帮我删掉 feature/payment-integration 分支

Claude 会先确认该分支确实已合并,然后执行:

bash
git branch -d feature/payment-integration

(使用 -d 而非 -D——如果分支未完全合并,Git 本身会拒绝删除并给出警告。)

暂存与恢复

正在一个分支上开发时,突然需要切到另一个分支处理紧急问题:

我需要在 feature/payment 分支上的工作先暂存一下,切换到 main 处理一个 hotfix

Claude 会:

bash
# 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 会:

bash
# 切回 feature 分支
git checkout feature/payment

# 恢复暂存的变更
git stash pop

8.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:

帮我创建这个功能的 PR

Claude 会:

  1. 推送当前分支到远程
  2. 运行 gh pr create 生成 PR
  3. 自动填写 PR 标题和描述(基于分支上的 commit 历史)
  4. 返回 PR 链接

生成的 PR 描述通常包含:

markdown
## 变更说明
新增用户通知功能,支持邮件和站内信两种通知方式。

## 变更文件
- 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 会执行:

bash
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 守卫

bash
# .git/hooks/pre-commit
npm run lint-staged

当 Claude 执行 git commit 时,如果它写的代码有 lint 错误,pre-commit hook 会阻止提交,错误信息会显示在对话中。Claude 会:

  1. 读取 lint 错误输出
  2. 自动修复问题
  3. 重新尝试提交

这形成了一个 "Claude 写代码 → hook 检查 → Claude 修复 → 通过后提交" 的自动化闭环。

场景:Commit Message 校验

bash
# .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/xxxfix/xxxrefactor/xxx——让 Claude 也能一目了然

diff 先行:提交前让 Claude 展示 diff

帮我看看将要提交的 diff,按文件汇总

在确认 commit message 之前,先看一遍实际变更内容。这能发现以下问题:

  • Claude 是否不小心修改了不该改的文件?
  • 是否有自动格式化导致的无关变更混入?
  • 是否有遗留的调试代码或注释?

一句话总结:永远让 Claude 先展示 git diff,再决定是否提交。 这不是不信任它——这是对你自己代码库的负责任态度。

配置 deny 规则:阻止危险 Git 操作

.claude/settings.json~/.claude/settings.json 中,明确禁止不可逆的危险操作:

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 每次对话都会读取它:

markdown
## 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-pickgit 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 自动校验质量

核心原则回顾

  1. Claude 感知状态,你做决策——Claude 帮你查、帮你分析、帮你建议,但 commit、merge、push 的最终决定权在你
  2. 频繁提交,小步快跑——每完成一个逻辑变更就提交,让 Git 历史成为可精准回退的安全网
  3. 永远先看 diff 再提交——不要跳过审查步骤,Claude 也可能不小心改错文件
  4. 分支隔离 Claude 的工作——每个任务一个分支,Claude 的变更不直接进入保护分支
  5. 配置 deny 规则阻止危险操作——force pushhard resetgit clean -fd 等不可逆操作应被配置锁定
  6. 别跳过 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 等级的调节策略,以及如何根据任务复杂度选择正确的模式组合。这是"基础篇"的最后一章,掌握后你将具备独立完成日常开发任务的全部技能。