Git Worktrees 并行
Git Worktrees 并行
Section titled “Git Worktrees 并行”并行开发最大的痛点不是任务调度,而是文件冲突。两个 Claude 同时改同一份代码,一个写完,另一个把它的改动覆盖了——典型的并行翻车现场。
Git worktree 是这个痛点的解药:它让每个 Claude Code 会话拿到自己独立的工作目录,各自的修改互不踩踏,但共享同一个仓库历史和远端。这是 Claude Code 的「分身术」——一个仓库,多个分身各自干活。
启动:claude -w / –worktree
Section titled “启动:claude -w / –worktree”--worktree / -w 在隔离的 worktree 里启动 Claude Code。默认 worktree 创建在 <repo>/.claude/worktrees/<name>/,分支名 worktree-<name>:
claude --worktree feature-auth# 等价于claude -w feature-auth在不同终端再跑一遍,名字取不一样的:
claude -w bugfix-123如果省略名字,Claude 自动生成一个(如 bright-running-fox):
claude --worktree在某目录第一次交互式用
--worktree前,先在该目录跑一次claude接受 workspace trust 弹窗。否则--worktree会报错并提示。非交互模式(带-p)会跳过 trust 检查。
记得把 .claude/worktrees/ 加到 .gitignore,免得 worktree 内容污染主 checkout 的未跟踪文件列表。
–tmux:开 tmux session
Section titled “–tmux:开 tmux session”--tmux 给 worktree 配一个 tmux 会话,让你能在多个 worktree 间快速切换:
claude -w feature-auth --tmux行为细节:
- 在 iTerm2 里默认用原生 panes(最丝滑)
- 传
--tmux=classic走传统 tmux - 必须搭配
--worktree使用
拉取指定 PR:# 或 PR URL
Section titled “拉取指定 PR:# 或 PR URL”要基于某个 PR 起一个 worktree 来审查或继续干活,传 PR 号(前缀 #)或完整 GitHub PR URL——Claude 会从 origin 拉取 pull/<number>/head,创建在 .claude/worktrees/pr-<number>:
claude -w "#1234"# 或完整 URLclaude -w "https://github.com/owner/repo/pull/1234"默认 worktree 从你仓库的默认分支 origin/HEAD 拉新分支——保证从干净的远端树开始。如果没远端或拉取失败,回退到本地 HEAD。
要始终从本地 HEAD 拉新分支(带上未推送的 commit 和 feature 分支状态),改 settings:
{ "worktree": { "baseRef": "head" }}baseRef 只接受 "fresh"(默认,远端)或 "head"(本地 HEAD),不接受任意 git ref。
把 gitignored 文件拷进 worktree
Section titled “把 gitignored 文件拷进 worktree”worktree 是全新 checkout,所以你主仓库里的 .env、.env.local 这类 gitignored 文件不存在。要自动把它们拷过去,在仓库根加一个 .worktreeinclude 文件,用 .gitignore 语法:
.env.env.localconfig/secrets.json只拷既匹配模式又是 gitignored 的文件——tracked 文件永远不会被复制。这对 --worktree、子代理 worktree、桌面端并行会话都生效。
子代理也能各自跑在独立 worktree 里,避免并行编辑冲突。直接告诉 Claude「use worktrees for your agents」,或者在自定义子代理 frontmatter 里加:
isolation: worktree每个子代理拿到一个临时 worktree,结束时若没改动会自动清理。
退出 worktree 会话时,行为取决于状态:
| 状态 | 行为 |
|---|---|
| 无未提交改动、无未跟踪文件、无新 commit | worktree 和分支自动删除 |
| 有未提交改动、未跟踪文件或新 commit | Claude 提示你选择保留或删除 |
非交互模式(-p) |
不自动清理(没有退出提示),手动 git worktree remove |
子代理和 后台会话 创建的 worktree 在 cleanupPeriodDays 设置到期后自动清理(前提是无未提交改动、无未跟踪文件、无未推送 commit)。你用 --worktree 创建的不会被这个 sweep 清理。
agent 跑的时候 Claude 会 git worktree lock 锁住 worktree,防止并发清理误删;agent 结束时释放锁。
手动管理 worktree
Section titled “手动管理 worktree”要更细控制位置和分支配置,直接用 git:
# 在新分支上创建git worktree add ../project-feature-a -b feature-a
# 从已有分支创建git worktree add ../project-bugfix bugfix-123
# 进 worktree 启动 Claudecd ../project-feature-a && claude
# 列出所有 worktreegit worktree list
# 用完删掉git worktree remove ../project-feature-a记得在每个新 worktree 里初始化开发环境——装依赖、配 venv、跑项目要求的 setup。
非 git 版本控制
Section titled “非 git 版本控制”SVN、Perforce、Mercurial 等系统可以配 WorktreeCreate 和 WorktreeRemove hooks 提供自定义创建/清理逻辑。因为 hook 完全替换默认 git 行为,.worktreeinclude 不再被处理——本地配置文件复制要在 hook 脚本里自己写。
{ "hooks": { "WorktreeCreate": [ { "hooks": [ { "type": "command", "command": "bash -c 'NAME=$(jq -r .name); DIR=\"$HOME/.claude/worktrees/$NAME\"; svn checkout https://svn.example.com/repo/trunk \"$DIR\" >&2 && echo \"$DIR\"'" } ] } ] }}Worktree 的甜区是长独立任务和机械活:
| 场景 | 为什么适合 |
|---|---|
| 跨多文件的大重构 | 改动隔离,主分支不脏 |
| 批量重命名 | 机械活,每个 worktree 一份独立改动 |
| 批量加错误处理 | 模式迁移,每个 PR 独立 |
| PR 审查 + 继续改 | #<PR号> 直接拉 PR 起一个 worktree |
| 并行开发多个 feature | 多终端多 worktree,互不踩 |
| 子代理并行执行 | isolation: worktree 自动隔离 |
「6 纪律」里有一条很硬的经验:worktree 是单条对吞吐量提升最大的改动——它把「等当前任务做完才能开始下一个」变成「同时开多个任务并行跑」。配合 后台会话,可以同时甩出去好几个长任务,每个都在自己 worktree 里独立干活。
--worktree给每个 Claude Code 会话一个独立工作树,像分身术一样让多个会话同时改代码而不互相覆盖。--tmux配 pane 切换,#<PR号>直接拉 PR,.worktreeinclude拷贝 gitignored 配置——这一套是并行开发的底层基础设施。
下一篇看 Agent Teams 多代理,多个 Claude Code 实例组成一个团队协同作战。👥