这篇适合谁、读完能做到什么
适合想同时让两三个 Claude Code 会话改同一个仓库、又不希望它们的文件修改互相踩到的开发者。读完你能用一个参数开出隔离的工作目录,知道会话结束时怎样清理,也知道隔离管不到哪些地方。
worktree 是什么,和并行会话怎么配合
git worktree 是同一个仓库的另一个工作目录。它有自己的文件和分支,但与主检出(main checkout)共享提交历史和远程仓库[1]。把每个 Claude Code 会话放进各自的 worktree,每个会话就拿到一份独立的文件副本去编辑:一个会话做新功能,另一个修 bug,两边的改动不会落在同一份文件上[1]。
开始前要准备什么
- 一个 git 仓库。worktree 是 git 的功能,项目必须先是 git 仓库。
- 信任这个目录。交互式运行时,如果以前没在这个目录里用过 Claude,先在目录里运行一次
claude,接受信任对话框;否则--worktree会报错退出。非交互的-p模式会跳过这项检查[1]。 - 一条
.gitignore规则。官方建议把.claude/worktrees/加进去,避免 worktree 里的内容在主检出里显示成未跟踪文件[1]。 - 每个 worktree 里都要装依赖。它是一份全新的检出,依赖和环境都要在里面重新准备[1]。
这几项里最容易漏的是最后两条:不装依赖,新会话就跑不起来;不配 .worktreeinclude,.env 之类的文件就会缺失。
第一步:开两个隔离会话
- 在仓库根目录运行带名字的命令:
claude --worktree feature-auth- Claude 会在
.claude/worktrees/feature-auth/下建一个 worktree,分支名为worktree-feature-auth,然后在里面启动[1]。 - 另开一个终端,换一个名字再运行一次,就得到第二个互不干扰的会话[1]。
如果省略名字,Claude 会生成类似 bright-running-fox 的名字[1]。
新 worktree 里缺的文件怎么办
新 worktree 里没有 .env 这类未纳入 git 的文件。如果每个 worktree 都要用到它们,可以在项目根目录放一个 .worktreeinclude,语法和 .gitignore 相同,Claude 创建 worktree 时会把匹配的文件复制进去[1]。只有同时匹配模式、又被 gitignore 忽略的文件才会复制,已经被 git 跟踪的文件不会重复复制[1]。
下面是一个例子,复制两个环境变量文件和一份密钥配置:
.env
.env.local
config/secrets.json会话内切换 worktree
除了命令行参数,也可以在会话里直接让 Claude 进入 worktree。它会调用 EnterWorktree 工具创建一个;要切换到 .claude/worktrees/ 下的另一个 worktree,把目标路径传给这个工具即可[1]。
如果目标路径在 .claude/worktrees/ 之外,Claude Code 会先请你批准。EnterWorktree 的权限规则,或者选择「不再询问」,都不能跳过这个提示,只有 bypassPermissions 模式会跳过[1]。
hooks 在这里有个坑:进入 worktree 之后,hook 命令里的 ${CLAUDE_PROJECT_DIR} 仍指向会话启动时的项目根目录。要拿到当前工作目录,得读 hook 输入 JSON 里的 cwd 字段[1]。
隔离是怎么执行的
会话在 worktree 里时,Claude Code 会拦下下面几类操作:
- 对主检出的
Edit、Write、NotebookEdit调用; - 工作目录解析到主检出的 Bash、PowerShell、Monitor 命令;
- 通过
git -C、--git-dir、GIT_DIR、GIT_WORK_TREE,或先cd进主检出,把 git 指到主检出的命令[1]。
让子智能体各用一个 worktree
子智能体(subagent)可以在自己的 worktree 里运行,并行修改就不会互相冲突。在自定义子智能体的 frontmatter 里加上 isolation: worktree,它每次都会在独立 worktree 中运行。.claude/agents/ 下的文件可以这样写[1]:
---
name: refactorer
description: Applies mechanical refactors across many files
isolation: worktree
---子智能体的临时 worktree 如果没有改动,结束时会被自动删除;有改动的则保留,直到定期清理能在不丢失工作的前提下把它删掉[1]。定期清理会删除早于 cleanupPeriodDays 设定天数的子智能体和后台会话 worktree,但凡还有未跟踪或已改动的文件、或未推送的提交,就保留不删[1]。
会话结束时怎么清理
交互式 worktree 会话退出时,Claude 会检查 worktree 里有没有删除后会丢失的内容。没有内容的未命名会话,worktree 会被自动删除;命名的会话则会先问你[1]。
如果里面有内容,Claude 会问你保留还是删除。保留会留下目录和分支;退出时打印的 claude --worktree <name> --resume 可以让你之后再回到这个会话[1]。
想手动删,就用 git worktree remove。文件有未提交或未跟踪的改动时加 --force;如果 git 因为锁定而拒绝,先运行 git worktree unlock[1]。
也可以直接用 git 创建
不用 Claude 的参数,直接用 git 创建 worktree 也行,然后在里面启动 Claude:
git worktree add ../project-feature-a -b feature-a
cd ../project-feature-a
claude这条命令会在新分支上创建 worktree[1]。
基础分支和拉取请求
默认情况下,新 worktree 从仓库的默认分支切出。把 worktree.baseRef 设为 "head",就改为从当前本地 HEAD 切出,未推送的提交和功能分支的状态会一起带过去[1]。
想基于某个拉取请求开工作区,可以在 --worktree 后面写 # 加编号,例如 claude --worktree "#1234"。引号是为了防止 shell 把 # 当成注释。Claude 会从 origin 拉取这个 PR 的头提交,worktree 建在 .claude/worktrees/pr-<编号> 下[1]。
限制和常见问题
并行会话多了以后,问题往往出在启动位置。index.lock 错误、LFS 指针文件这类报错,大多能在启动前检查出来:先确认在 worktree 根目录启动,再确认大文件已经拉取。
- **
index.lock错误**:默认情况下,如果在 worktree 的子目录里运行claude,git 命令会报index.lock错误。开启沙箱后,git commit等命令能在 worktree 根目录的会话里正常工作[1]。 - 共享的东西:worktree 和主检出共享
.git目录、项目级插件和权限审批。在 worktree 里选择「是,且不再询问」某条 Bash 命令,这条规则会写进主检出的.claude/settings.local.json[1]。 - Git LFS:如果用
git lfs install --local装过 LFS,Claude 创建的 worktree 里会是 LFS 指针文件,不是真实文件。在 worktree 里运行git lfs pull即可取回[1]。
下一步
子智能体隔离的完整说明,以及 worktree 的其他细节,都可以直接看官方文档[1]。
来源
- 1Run parallel sessions with worktreesAnthropic Claude Code docs
引用本页: Claude Code 并行开发:用 git worktree 同时跑多个会话. TellWorld, https://www.tellworld.net/zh/practice/practice-claude-code-worktrees. 更新于 2026-11-14