跳转到内容

Git Worktrees 并行

并行开发最大的痛点不是任务调度,而是文件冲突。两个 Claude 同时改同一份代码,一个写完,另一个把它的改动覆盖了——典型的并行翻车现场。

Git worktree 是这个痛点的解药:它让每个 Claude Code 会话拿到自己独立的工作目录,各自的修改互不踩踏,但共享同一个仓库历史和远端。这是 Claude Code 的「分身术」——一个仓库,多个分身各自干活。

--worktree / -w 在隔离的 worktree 里启动 Claude Code。默认 worktree 创建在 <repo>/.claude/worktrees/<name>/,分支名 worktree-<name>

Terminal window
claude --worktree feature-auth
# 等价于
claude -w feature-auth

在不同终端再跑一遍,名字取不一样的:

Terminal window
claude -w bugfix-123

如果省略名字,Claude 自动生成一个(如 bright-running-fox):

Terminal window
claude --worktree

在某目录第一次交互式用 --worktree 前,先在该目录跑一次 claude 接受 workspace trust 弹窗。否则 --worktree 会报错并提示。非交互模式(带 -p)会跳过 trust 检查。

记得把 .claude/worktrees/ 加到 .gitignore,免得 worktree 内容污染主 checkout 的未跟踪文件列表。

--tmux 给 worktree 配一个 tmux 会话,让你能在多个 worktree 间快速切换:

Terminal window
claude -w feature-auth --tmux

行为细节:

  • 在 iTerm2 里默认用原生 panes(最丝滑)
  • --tmux=classic 走传统 tmux
  • 必须搭配 --worktree 使用

要基于某个 PR 起一个 worktree 来审查或继续干活,传 PR 号(前缀 #)或完整 GitHub PR URL——Claude 会从 origin 拉取 pull/<number>/head,创建在 .claude/worktrees/pr-<number>

Terminal window
claude -w "#1234"
# 或完整 URL
claude -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。

worktree 是全新 checkout,所以你主仓库里的 .env.env.local 这类 gitignored 文件不存在。要自动把它们拷过去,在仓库根加一个 .worktreeinclude 文件,用 .gitignore 语法:

.env
.env.local
config/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 结束时释放锁。

要更细控制位置和分支配置,直接用 git:

Terminal window
# 在新分支上创建
git worktree add ../project-feature-a -b feature-a
# 从已有分支创建
git worktree add ../project-bugfix bugfix-123
# 进 worktree 启动 Claude
cd ../project-feature-a && claude
# 列出所有 worktree
git worktree list
# 用完删掉
git worktree remove ../project-feature-a

记得在每个新 worktree 里初始化开发环境——装依赖、配 venv、跑项目要求的 setup。

SVN、Perforce、Mercurial 等系统可以配 WorktreeCreateWorktreeRemove 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 实例组成一个团队协同作战。👥