并行多会话:git worktree 隔离、多任务并发的正确姿势
单线程是浪费,乱并行是灾难
见过两种开发者:一种永远单会话串行,Claude 在跑测试时自己干等;一种开五个终端同时改同一份代码,最后互相覆盖、git 状态一团糟。并行多会话这章就是教你走中间那条路:用隔离换取真正的并发。
核心工具是 git worktree——同一个仓库的多个独立工作目录,各自检各自分支,共享仓库历史。给每个 Claude 会话配一个 worktree,它们就物理上不可能互相覆盖。
--worktree:一条命令的隔离
# 终端 1:开发鉴权功能(创建 .claude/worktrees/feature-auth/,分支 worktree-feature-auth)
claude --worktree feature-auth
# 终端 2:修支付 bug,完全隔离
claude --worktree fix-payment
# 不想取名也行,自动生成如 bright-running-fox
claude --worktree
默认行为:worktree 建在仓库根的 .claude/worktrees/<名字>/ 下,分支名 worktree-<名字>,基于远端默认分支(新鲜的 main,24 小时内没 fetch 过会自动 fetch,5 秒超时兜底)。建议把 .claude/worktrees/ 加进 .gitignore。
进阶变体都值得知道:
claude --worktree "#1234" # 直接从 PR #1234 建分支(支持 GitHub/GitLab URL)
// 想基于你当前未推送的工作而不是干净的 main:
{ "worktree": { "baseRef": "head" } }
gitignore 的文件(比如 .env)不会自动进新 worktree——在仓库根放一个 .worktreeinclude 文件列出它们,新建 worktree 时自动拷贝。首次在目录里跑交互会话要先接受工作区信任,-p 模式跳过这个检查。
隔离是强制的,不只是建议
这是很多人没意识到的一点:worktree 会话里的隔离检查是 Claude Code 强制执行的,不是靠模型自觉。四道检查覆盖主会话和它派的所有子代理:
| 检查 | 拦截什么 |
|---|---|
| 文件编辑目标 | 禁止 Edit/Write 指向主检出目录 |
| 命令工作目录 | 禁止 Bash 等命令把工作目录解析到主检出 |
| Git 重定向 | 禁止 git -C、GIT_DIR 等把 git 指向主检出 |
| 命令形态 | 解析不了命令文本时宁可拦截(此检查不可关闭) |
被拦的命令 Claude 会收到带原因的错误并自行改写(比如拆成纯命令)。注意边界:检查不追踪 shell 命令实际写了哪些文件——cp 写进主检出不会被这些检查拦,那是权限和沙箱的领域。
清理与恢复:别让 worktree 变垃圾场
退出交互的 worktree 会话时,Claude 会检查里面有没有活:干净的自动清掉(未命名会话),有未提交工作的会问你留不留。留了的话,退出提示会告诉你恢复命令:
claude --worktree feature-auth --resume # 回到那个 worktree 接着干
恢复逻辑有兜底:worktree 目录被删了,会话就在你启动的目录恢复并解除绑定;worktree 还在就自动回到 worktree。子代理也能配持久隔离——frontmatter 加 isolation: worktree,这个子代理每次都在自己的临时 worktree 里干活(没改动自动删,有改动留到定期清扫)。/batch 大规模并行就是靠这套机制,每个独立单元一个 worktree。
多会话监控:agent view 与消息互通
两个终端窗口来回切太累?把会话丢后台统一监控:会话里跑 /background(或 /bg),终端立刻解放,会话继续跑;claude agents 命令看所有后台会话列表。会话之间还能直接通信——你在 A 会话里说"把发现告诉 B 会话",Claude 可以跨会话传话;/list-agents 列出当前可发消息的所有对象。
会话内进 worktree:EnterWorktree 工具
除了启动时指定,还能会话中途让 Claude 进 worktree——直接说"在 worktree 里干这个活",它会用 EnterWorktree 工具创建并切换。进 .claude/worktrees/ 内的路径不需要确认,进外面的路径要你批准(因为整个工作目录、写权限和项目配置都跟着搬过去)。同样的,它能 ExitWorktree 退回主检出,转录跟着目录走(会话记录归到当前工作目录名下)。
hook 路径有个要知道的细节:进 worktree 后 ${CLAUDE_PROJECT_DIR} 仍指向会话启动时的项目根,hook 输入 JSON 里的 cwd 才是 worktree 路径。用 hook 做格式化的同学不用动配置,想让 hook 感知 worktree 的才需要改读 cwd。
与子代理的组合拳
两层并行叠加是重度用户的常规操作:每个 worktree 会话内部再派子代理。还可以更进一步——让子代理也各占一个 worktree:给自定义子代理的 frontmatter 加 isolation: worktree,或临时说一句"用 worktree 隔离你的代理"。典型配置:
---
name: refactorer
description: 跨多文件执行机械性重构
isolation: worktree
---
按要求在所有受影响文件上执行重构,然后跑测试并汇报结果。
每个子代理拿到临时 worktree,无改动自动删除、有改动保留到定期清扫(超过 cleanupPeriodDays 的会被清,清扫会保护仍有未推送提交的 worktree)。子代理 worktree 的起始分支同样受 worktree.baseRef 控制。清扫期间 Claude Code 对运行中的 worktree 持 git worktree lock,不会出现"干着干着目录被清了"的事故。
并行方式总选型
Claude Code 的并行机制不止 worktree 一种,收尾给一张全家福对照,帮你按任务选武器:
| 机制 | 隔离什么 | 适用 | 成本 |
|---|---|---|---|
多终端 + --worktree |
文件系统 | 互不相干的 2-4 个任务 | 低 |
/background 后台会话 |
终端注意力 | 长任务挂机 | 低 |
/fork 复制会话 |
全部(新会话) | 当前工作分身试另一条路 | 中 |
| 子代理 | 上下文 | 单会话内的调研/副活 | 中 |
isolation: worktree 子代理 |
文件系统 + 上下文 | 会话内多路会改文件的活 | 中高 |
/batch |
每单元独立 worktree | 大改造拆 5-30 个单元 | 高 |
| Agent 团队 | 完整实例 | 需要互相对话的协作 | 高 |
选型的第一问永远是:这些任务会碰同一批文件吗? 会——worktree 层隔离;不会——上下文层隔离(子代理)就够。第二问是:需要互相沟通吗? 需要——上团队;不需要——任何并行机制都行。
一套可抄的并行工作法
场景:今天要做 A 功能、B bug 修复、C 依赖升级
终端 1 claude --worktree feat-a 计划模式起步,批准后 auto 执行
终端 2 claude --worktree fix-b 直接 auto 模式干
终端 3 claude --worktree up-deps 让它升级并跑全量测试
每完成一个:worktree 里提交 → 合 PR → 退出会话选清理
中途想看进度:claude agents 或逐终端 Ctrl+O 看转录
三条纪律:互不相干才并行(改同一批文件的任务排队别并行);每个 worktree 保持单一任务(又混起来就失去隔离意义了);每天清一次 worktree(git worktree list 过一遍,僵尸目录及时清)。worktree 机制对非 git 仓库不可用,但有 WorktreeCreate/WorktreeRemove hook 可以自建替代逻辑,细节见官方 worktree 文档。
本章由 WorkBuddy 原创整理,事实性内容参考 Claude Code 官方文档。
