Skip to content

第 13 章 Git 工作流与 Code Review

Git 是人类对代码变更保留的最终控制面。Claude Code 的 /commit /pr /code-review /security-review /review 把提交与审查的体力活自动化,但人工 diff 审查不可让渡——Claude 说"修复了"不算数,git diff 看到的才算数。这一章讲清楚五条命令的真实语义、effort 档取舍、GitHub Actions 集成,以及哪些事绝对不能交给机器。

13.1 结论:五条命令各管一段,人工 diff 是终审

本章涉及的五条命令都是 Bundled Skill(官方随包附带,装好即有,本质是 skill,可被覆盖),它们的语义边界是本章的核心:

命令作用对象产生状态变化内置类别
/commit当前工作树是,执行 git commitBundled Skill
/pr当前分支是,创建 PRBundled Skill
/code-review当前 diff否(默认)/ 是(--fix)Bundled Skill
/security-review待提交变更否(只读审查)Bundled Skill
/reviewGitHub PR(远程)否(只读审查,可 --comment)Bundled Skill

关键区分:

  • /code-review本地 diff——你工作区里还没提交的改动,或当前分支相对 main 的差异
  • /reviewGitHub PR——远程仓库里已存在的 Pull Request,通过 gh CLI 拉取

两者对象不同,不要混用。本地改完还没推,用 /code-review;PR 已开、要看别人开的 PR,用 /review

完整的提交前流水线:

text
working tree

机械检查(git diff --check / lint / typecheck / test)  ← 先机器

Claude 建立变更清单(只读)                              ← 再模型,语义分组

/code-review + /security-review                        ← 模型审查

人工 git diff 审查                                      ← 人类终审,不可让渡

/commit 或 /pr                                          ← 产生状态

不要把"生成 commit message"和"执行 git commit"混为一个权限。前者是只读分析,后者产生持久状态。/commit 会直接执行提交,所以它必须排在人工审查之后,而不是之前。

13.2 提交前的机械检查:先机器后模型

在让模型做语义审查前,先清除机器能直接发现的问题。模型推理很贵,不该浪费在尾随空格和冲突标记上。

bash
git diff --check
npm run lint
npm run typecheck
npm test

git diff --check 能发现尾随空格和冲突标记,这类问题不需要消耗模型推理:

text
$ git diff --check
apps/api/src/routes/user-audit-events.ts:42: trailing whitespace.

预期输出:无输出表示干净;有输出则定位到具体行。

验证:修复后重跑,直到 git diff --check 静默。

失败边界:跳过 git diff --check 直接 /commit,会把尾随空格、冲突标记一起写进历史;后续 rebase 或 cherry-pick 时冲突标记会再次浮现。

13.3 让 Claude 先建立变更清单(只读)

进入 Claude Code 后,先让模型只读地建立变更清单,不要修改文件、不要暂存、不要提交:

text
运行 `git status --short`、`git diff --stat` 和 `git diff`。
不要修改文件,不要暂存,不要提交。

输出按语义分组:
1. 用户可见行为变化
2. 内部重构
3. 测试变化
4. 配置或依赖变化
5. 可疑的无关改动

模拟工具输出:

text
● Bash(git status --short)
 M apps/api/src/app.ts
 M apps/web/src/pages/UserDetailPage.tsx
 M packages/auth/src/can.ts
?? apps/api/src/routes/user-audit-events.ts
?? apps/web/src/components/AuditEventList.tsx
?? packages/contracts/src/audit-event.ts

● Bash(git diff --stat)
 9 files changed, 286 insertions(+), 14 deletions(-)

Claude 的摘要应该按语义分组,而不是逐文件复述:

text
Behavior:
- Adds a protected audit-events endpoint.
- Renders audit events on the user detail page.

Authorization:
- Allows admin or self; other users receive 403 before repository access.

Tests:
- Adds role matrix, no-query-on-forbidden, rendering, empty, error cases.

Unrelated:
- package-lock.json changed although no dependency was added.

验证:对照 git diff --stat 的文件列表,确认 Claude 没有遗漏文件,也没有把无关改动混进功能描述。最后一项"Unrelated"最重要——package-lock.json 的无关变化应该先调查,而不是跟着功能一起提交。

失败边界:如果 Claude 在这一步就开始 git add 或修改文件,立即中止,重新限定范围。建立清单是只读操作,任何写动作都违反流程。

13.4 /commit:Conventional Commit 自动生成

/commit 是 Bundled Skill,它会基于当前 git diff 生成符合 Conventional Commits 规范的提交信息,然后执行 git commit

text
/commit

约束规范(由 skill 内置,但可在 prompt 中追加):

  • type 限定为 feat fix refactor test docs chore perf build ci style
  • scope 使用受影响的产品模块(如 users auth api)
  • subject 使用 imperative mood(祈使句),不超过 72 字符
  • body 解释 why,不逐文件复述 what
  • footer 标注 BREAKING CHANGE、关联 issue

预期输出:

text
feat(users): add authorized audit event history

Expose paginated audit events to administrators and the target user while
rejecting cross-user access before data lookup. Add the user-detail UI and
cover authorization, empty, error, and rendering states.

[main abc1234] feat(users): add authorized audit event history
 9 files changed, 286 insertions(+), 14 deletions(-)

如果 diff 同时包含无关依赖升级,Claude 应建议拆分:

text
Split recommended:
1. feat(users): add authorized audit event history
2. chore(deps): update test tooling

已中止提交,请先拆分改动。

验证:提交后跑 git log -1 --stat 确认 commit message、作者、改动文件与审查对象一致。

失败边界:

  1. 未跑测试就 /commit——/commit 不会替你跑测试,它只看 diff。测试挂了照样能提交成功,脏代码就进历史了。务必先跑 npm test/commit
  2. 盲目信任 message——Claude 生成的 message 可能漏掉 BREAKING CHANGE,或把 feat 误标为 fix。提交前看一眼 message,不对就 git commit --amend 改。
  3. /commit 会真实提交——它不是"生成 message 让你手动 commit",而是直接执行。如果你想先看 message 再决定,用下一节的 print mode 方式。

只生成 message 不提交(适合 CI 或谨慎场景):

bash
git diff --cached | claude -p \
  --tools "" \
  "根据输入的 staged diff 生成 Conventional Commit message,只输出 message"

--tools "" 禁用工具,Claude 只能分析 stdin,适合最小权限自动化。人类确认后再手动 git commit

13.5 /pr:创建 Pull Request

/pr 是 Bundled Skill,基于当前分支相对 base 分支的改动,生成 PR 标题与描述,然后通过 gh CLI 创建 PR。

text
/pr

预期输出:

text
PR title: feat(users): add authorized audit event history

PR body:
## Summary
- Expose paginated audit events to administrators and the target user
- Reject cross-user access before data lookup
- Add user-detail UI with empty/error/loading states

## Test plan
- [x] Role matrix tests (admin/self/other)
- [x] No-query-on-forbidden test
- [x] Rendering and empty-state tests
- [ ] Manual smoke test on staging

Creating PR...
https://github.com/org/repo/pull/142

PR body 通常包含:Summary(改了什么、为什么)、Test plan(验证清单)、关联 issue。gh pr create 执行后返回 PR URL。

验证:gh pr view 142 --web 打开 PR 页面,确认标题、描述、base 分支、 reviewers 配置正确。

失败边界:

  1. 未推送就 /pr——/pr 会先 git push -u origin HEAD,如果分支有未推送的 commit,这一步会产生推送动作。如果你不想推送(比如还没审查完),不要跑 /pr
  2. base 分支选错——/pr 默认用仓库的 default branch 作为 base。如果你要 PR 到 develop 而不是 main,显式指定,否则 PR 会开错目标。
  3. PR 描述泄露 secrets——Claude 生成 body 时可能把 diff 里的测试 token、内部 URL 写进描述。推送前扫一眼 body。

13.6 /code-review:当前 diff 审查

/code-review 是本章的主力审查命令。它审查当前 diff(工作区未提交改动 + 当前分支相对 base 的差异),支持 effort 档与两个动作选项。

13.6.1 effort 档取舍

text
/code-review                # 默认 medium
/code-review low
/code-review high
/code-review xhigh
/code-review max

五档的取舍是少而精 vs 广而杂:

档位行为适用场景
low少量、高置信 finding,几乎无误报快速过一遍小改动、临提交前最后一道闸
medium平衡,默认档日常 feature 开发
high广覆盖,可能包含中等置信问题重构、安全敏感改动
xhigh更广,会报告需要进一步确认的疑似问题大型 diff、跨模块影响
max全覆盖,包含低置信推测关键路径(支付、鉴权、加密)上线前

核心取舍:低档少而高置信,高档广覆盖但噪音多max 档会报告"疑似问题",需要你人工甄别,不要见到 finding 就改。

13.6.2 审查范围限定

只审查某个文件:

text
/code-review high apps/api/src/routes/user-audit-events.ts

只审查某个目录:

text
/code-review high apps/api/src/routes/

范围限定能减少噪音、加快审查,适合大 diff 里只关心某块改动的场景。

13.6.3 --fix:应用修复

text
/code-review high --fix

--fix 会在审查后直接修改工作树,应用高置信度修复。

预期输出:

text
[High] Cursor accepted without binding to userId
File: apps/api/src/repositories/audit-event-repository.ts:41

Applied fix: bind cursor payload to userId

[Medium] Missing error case for empty cursor
File: apps/api/src/routes/user-audit-events.ts:78

Applied fix: add 400 response for malformed cursor

2 findings, 2 fixed. Re-run tests to verify.

验证:--fix 后必须:

  1. git diff 看修复内容,确认修的是问题、不是症状
  2. 重跑 npm testnpm run typecheck
  3. 再次 /code-review 确认 finding 已消除

失败边界:--fix 会修改工作树。运行前先 git stash 或确认工作区干净(除了待审查的改动),否则修复与你的改动混在一起难以回退。--fix必须重跑测试,修复本身可能引入新问题。

13.6.4 --comment:贴 PR 评论

text
/code-review high --comment

--comment 把 finding 作为 inline 评论贴到 GitHub PR 对应的代码行上。需要当前分支已开 PR(gh CLI 能找到)。

预期输出:每条 finding 生成一条 PR inline comment,挂在对应文件行号上。

失败边界:--comment 会向远程 PR 写入评论。如果你在本地还没开 PR,或 PR 是别人的,不要用 --comment——它会失败或贴错地方。

13.6.5 有效 finding vs 无效 finding

一个有效的 review finding 应包含:

text
[High] Cursor is accepted without binding it to userId

The repository decodes a global cursor and uses its event ID directly.
An authorized user could reuse a cursor from another user and cause the
query to start from an unrelated row. Bind the cursor payload to userId
or include userId in the database predicate.

File: apps/api/src/repositories/audit-event-repository.ts:41

无效 finding 通常是:

text
Consider improving error handling.

它没有可触发路径、影响和修复位置,不能直接行动。如果你看到大量这类 finding,说明 effort 档开太高了,降到 mediumlow

可以追加 prompt 控制噪音:

text
只报告能由当前 diff 引入、可给出触发路径、且置信度高的问题。
不要报告纯风格偏好。
按 correctness、security、performance 分类。

13.7 /security-review:安全审查

/security-review 专做安全审查,关注攻击面而非代码质量。它对待提交变更做只读审查,不修改文件。

text
/security-review

针对常见 Web 服务,重点检查:

  • IDOR:是否只验证"已登录",却没验证目标用户
  • 信息泄露:403 404 是否暴露用户存在性(timing、消息差异)
  • 注入:cursor、排序字段、过滤条件是否进入原始 SQL
  • 越权缓存:响应是否被跨用户缓存(CDN、浏览器缓存)
  • 敏感数据:响应是否包含 token、邮箱、IP 等不应展示字段
  • 资源耗尽:分页 limit 是否有上限、是否有无界查询
  • 日志注入:用户输入是否直接写入结构化日志(日志伪造、SIEM 注入)
  • SSRF:用户控制的 URL 是否被服务端请求
  • 密钥泄露:diff 里是否硬编码 token、密钥、连接串

可以追加领域约束:

text
/security-review

额外检查:
- 任何 member 都不能读取其他用户事件
- 未授权请求不能触发 repository 查询
- API 不能返回 audit payload 中的 metadata.secret
- cursor 必须和 target user 绑定

模拟发现:

text
[Critical] API returns raw metadata from storage

The route maps repository rows with `{ ...row }`, which includes
`metadata.secret`. This field can contain OAuth provider details.
Construct `AuditEventDto` explicitly and return only contract fields.

File: apps/api/src/routes/user-audit-events.ts:55

修复方式应是输出白名单:

ts
return {
  id: row.id,
  actorName: row.actorName,
  action: row.action,
  createdAt: row.createdAt.toISOString()
};

而不是黑名单删除:

ts
delete row.metadata.secret;
return row;

白名单能抵御未来数据库新增敏感字段时的意外暴露——新增字段不会自动进白名单,但会自动进 { ...row }

验证:/security-review 报告的 Critical/High 必须逐条确认修复,或在 prompt 中明确说明为何不修(误报、已由其他层防御)。修复后重跑 /security-review 确认 finding 消失。

失败边界:

  1. /security-review 不是渗透测试——它做静态审查,看不到运行时行为、配置、依赖漏洞。生产前仍需跑 npm audit、SCA 工具、SAST 扫描。
  2. 领域知识缺失——Claude 不知道你的业务规则("member 不能读其他用户事件"这类约束必须显式告知)。
  3. 误报与漏报并存——安全审查的 recall 比 precision 重要,宁可多报也别漏。但多报意味着你需要人工甄别,不能见到 finding 就改。

13.8 /review:审查 GitHub PR

/review 审查远程 GitHub PR,与 /code-review 审本地 diff 的语义不同。

text
/review 142

或:

text
/review https://github.com/org/repo/pull/142

/review 通过 gh CLI 拉取 PR 的 diff、metadata、CI 状态、已有评论,做完整审查。适合:

  • 审查同事开的 PR(你本地没有这个分支)
  • 审查依赖库的 PR(开源贡献 review)
  • 在 PR 合并前做最后一道独立审查

预期输出:

text
PR #142: feat(users): add authorized audit event history
Author: alice, base: main, +286/-14, CI: passing

Findings:
[High] Cursor not bound to userId (audit-event-repository.ts:41)
[Medium] Missing test for empty cursor (user-audit-events.ts:78)
[Low] Typo in error message (AuditEventList.tsx:23)

Overall: Request changes. Address High before merge.

可附加选项(视 skill 版本):

text
/review 142 --comment        # 把 finding 贴为 PR inline comment
/review 142 --approve        # 审查通过,approve PR
/review 142 --request-changes  # 请求修改

验证:审查后 gh pr view 142 确认评论已贴、状态已更新。

失败边界:

  1. /review/code-review 混用——本地还没 push 的改动,/review 看不到(它看远程 PR);远程别人开的 PR,/code-review 也看不到(它看本地 diff)。选错命令会得到空结果或审查错对象。
  2. --approve 滥用——不要让 Claude 自动 approve PR。approve 是人类的合并决策,涉及业务、依赖、发布窗口判断,Claude 看不到全貌。让 Claude 报告 finding,人类做 approve 决策。
  3. CI 状态盲区——/review 会读 CI 状态,但不会替你跑 CI。如果 PR 的 CI 还在 pending,等 CI 跑完再 review,否则可能漏掉测试失败引入的问题。

13.9 GitHub Actions 中的 Claude:anthropics/claude-code-action

除了在本地用 Claude Code,你还可以把 Claude 集成进 GitHub Actions,让 PR/issue 中的 @claude 触发自动响应。官方 action 是 anthropics/claude-code-action

13.9.1 典型 YAML 示例

以下是一个完整的 GitHub Actions workflow 示例(标注:示例,需替换 org/repo 与 secrets):

yaml
# .github/workflows/claude.yml
# 示例:PR/issue 评论中 @claude 触发 Claude Code 响应
# 核对日期:2026-07-08,anthropics/claude-code-action@v1

name: Claude Code

on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]
  issues:
    types: [opened, assigned]

jobs:
  claude:
    # 仅在评论包含 @claude 时触发
    if: |
      (github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment')
      && contains(github.event.comment.body, '@claude')
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
      issues: write
      id-token: write
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Run Claude Code
        uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          # 可选:指定模型(默认 Sonnet)
          # model: claude-sonnet-5
          # 可选:限定允许的工具,收紧权限
          # allowed_tools: "Read,Grep,Glob,Bash(git diff *)"
          # 可选:直接触发而非等 @claude
          # direct_trigger: true

13.9.2 触发方式

  • PR 评论中 @claude:Claude 拉取 PR diff、评论上下文,执行任务(改代码、回答问题、修 bug)
  • issue 评论中 @claude:Claude 读取 issue 描述与评论,响应
  • @claude + 指令:@claude fix the failing test @claude review this PR for security issues

13.9.3 权限收紧

claude-code-action 默认权限较宽(可写 contents、PR、issues)。生产环境务必收紧:

yaml
allowed_tools: "Read,Grep,Glob,Bash(git status *),Bash(git diff *)"

这样 Claude 只能只读分析,不能直接改代码、不能 push。需要它改代码时,再通过 PR 评论显式授权。

13.9.4 密钥管理(失败边界)

yaml
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}

关键纪律:

  1. API key 必须放 GitHub Secrets,绝不能硬编码在 workflow 文件里
  2. Secrets 不会自动脱敏日志——如果 workflow 把 ANTHROPIC_API_KEY echo 到日志,Secrets 脱敏可能漏掉变体(如 base64、截断)。不要在 step 里打印环境变量
  3. fork PR 的陷阱——默认情况下,fork PR 触发的 workflow 无法访问 secrets(pull_request 事件来自 fork 时 secrets 不注入)。但 issue_comment 事件可以。如果你用 pull_request 触发且允许 fork,务必在 workflow 里加 if: github.event.pull_request.head.repo.full_name == github.repository 限制只跑自家仓库
  4. GITHUB_TOKENANTHROPIC_API_KEY 分离——GITHUB_TOKEN 是 GitHub 给的,权限受限;ANTHROPIC_API_KEY 是你的 Anthropic 账户 key,花钱。两者都要放 Secrets,不要混用

验证:workflow 跑完后,在 Actions 日志里确认 Claude 的输出符合预期,且日志里没有明文 key。定期在 Anthropic console 查 API 用量,异常飙升说明 key 泄露或被滥用。

失败边界:

  1. CI 中密钥泄露——这是最高危的失败。一旦 key 进日志、进 PR 评论、进 artifact,立即在 Anthropic console 吊销 key,重新生成。不要"等下再处理"。
  2. @claude 被滥用——任何能评论 PR/issue 的人都能触发 @claude,消耗你的 API 额度。用 if 条件限制触发者(如只允许 org member):
    yaml
    if: |
      contains(github.event.comment.body, '@claude')
      && contains(fromJson('["alice","bob","carol"]'), github.event.comment.user.login)
  3. Claude 直接 push 到 main——contents: write 权限下,Claude 可以直接 push。务必让 Claude 走 PR 流程(改到 feature branch、开 PR),而不是直接 push main。在 claude-code-action 配置里禁用直接 push,或用 branch protection rule 锁死 main。

13.10 人工 diff 审查:不可让渡的控制面

前面所有自动化——/code-review /security-review /review——都是辅助,不是替代。人类读 git diff 是不可让渡的终审。

为什么?因为 Claude 的审查有已知盲区:

  • 看不到运行时行为——它读代码,不跑代码。内存泄漏、竞态、性能退化,静态审查很难发现
  • 看不到业务上下文——它不知道这个改动是否符合产品需求、是否破坏了未写文档的兼容性承诺
  • 会被精心构造的代码欺骗——变量名误导、注释与实现不符、看似无害的重构实际改变了语义
  • effort 档越高噪音越多——max 档会报告大量低置信 finding,你可能疲于甄别而漏掉真问题

人工 diff 审查的标准动作:

bash
# 1. 看工作区改动(未暂存)
git diff

# 2. 看暂存区改动(已 git add)
git diff --cached

# 3. 看当前分支相对 main 的全部改动
git diff main...HEAD

# 4. 看某个文件的改动
git diff apps/api/src/routes/user-audit-events.ts

# 5. 逐行审查(交互式)
git diff --cached -p

审查清单:

text
重新读取最终 git diff,只报告问题,不修改文件:
1. 是否残留调试代码、console.log、TODO、注释掉的代码
2. 是否包含秘密、token、内部 URL、连接串
3. 是否修改了依赖或 lockfile(package-lock.json、yarn.lock、go.sum)
4. 是否缺少失败路径测试(只测了 happy path)
5. 是否有与任务无关的改动(混入的格式化、无关重构)
6. 是否有看似无害但语义变化的改动(如 === 改 ==、同步改异步)
7. 是否删除了错误处理或降级逻辑
8. 是否扩大了权限范围(新增的 endpoint 没鉴权)

关键陷阱:审查工作树、却提交另一个 staged diff。这是常见流程漏洞:

bash
# 你审查的是工作区
git diff

# 但提交的是暂存区
git commit

# 两者可能不一致!

正确做法:

bash
# 1. 审查工作区
git diff

# 2. 暂存要提交的改动
git add -p   # 交互式暂存,逐块确认

# 3. 再次审查暂存区
git diff --cached

# 4. 确认一致后提交
git commit

只有在你刚刚审查过的 diffgit diff --cached 完全一致时,才提交。

13.11 失败边界汇总

本章所有命令的失败边界,集中在三类:

13.11.1 盲目信任 /code-review

/code-review 报告"无 finding"不等于代码没问题。它可能:

  • 漏掉只有运行时才暴露的 bug
  • low 档下只报高置信问题,中等置信的真问题被过滤
  • 被精心构造的代码欺骗(变量名误导、注释不符)

对策:/code-review 是辅助,不是替代。关键路径(支付、鉴权、加密)必须人工逐行审查,且 effort 档开到 high 以上。

13.11.2 未跑测试就 commit

/commit 不会替你跑测试。测试挂了照样能提交成功,脏代码进历史。

对策:提交前流水线固定为:

bash
git diff --check
npm run lint
npm run typecheck
npm test
# 全绿后再 /commit

把这套命令写进 Hook(第 14 章)或 CI,让机器强制执行。

13.11.3 CI 中密钥泄露

anthropics/claude-code-action 需要 ANTHROPIC_API_KEY。一旦泄露:

  • 攻击者可以冒用你的账户调用 Claude API,产生巨额账单
  • 如果 Claude 有仓库写权限,攻击者可以通过 @claude 指令让 Claude 改代码、开 PR、甚至 push

对策:

  1. API key 只放 GitHub Secrets,绝不硬编码
  2. workflow 里限制 @claude 触发者(只允许 org member)
  3. allowed_tools 收紧 Claude 权限,默认只读
  4. branch protection 锁死 main,禁止直接 push
  5. 定期在 Anthropic console 查用量,异常立即吊销 key
  6. fork PR 不触发带 secrets 的 workflow

13.11.4 其他边界

  • /commit 会真实提交——不是生成 message 让你手动 commit。想先看 message,用 print mode
  • /pr 会真实推送 + 开 PR——不想推送就别跑
  • --fix 会修改工作树——跑前确认工作区状态,跑后重跑测试
  • --comment 会写远程 PR——本地没 PR 或 PR 是别人的,不要用
  • /review --approve 滥用——approve 是人类合并决策,不让 Claude 自动 approve
  • effort 档过高——max 档噪音多,疲于甄别反而漏掉真问题。日常用 medium,关键路径用 high/xhigh

13.12 小结

Git 是人类对代码变更的最终控制面。Claude Code 的五条命令把提交与审查的体力活自动化:

  • /commit——生成 Conventional Commit 并执行提交
  • /pr——基于改动创建 Pull Request
  • /code-review——审查当前 diff,支持 effort 档、--fix--comment
  • /security-review——对待提交变更做安全审查
  • /review——审查远程 GitHub PR(与 /code-review 审本地 diff 的语义区别)

GitHub Actions 中的 anthropics/claude-code-action 把 Claude 集成进 CI,PR/issue 中 @claude 触发,但密钥管理与权限收紧是不可妥协的纪律。

核心心法不变:你做架构决策和关键审查,Claude 做实现和探索。提交前的最后一步,永远是 git diff 人工审查,而不是 Claude 的一句"已修复"。


上一章:测试与质量保障
下一章:Hooks 与自动化


下一章:Hooks 系统 | 返回目录