用 Git Worktrees 跑并行 AI Agent:多个 Agent 同时改代码互不打架
用 git worktree 让多个 AI 编程 agent 并行的实操指南:独立工作区 + 独立分支,含目录布局、依赖隔离、合并流程、踩坑与 v2.1.309 隔离修复。
发布 2026-06-28更新 2026-11-01核实 2026-10-24适用场景
当你想同时让多个 AI agent 干活——一个修 bug、一个写新功能、一个重构——它们如果都在同一个工作目录里,会互相覆盖文件、抢着切分支、把对方改了一半的代码当成最新状态。git worktree 是这个问题的标准解法:一个仓库、多个工作区、各自独立的分支和文件系统状态。
适合:
- 想跑「双 agent 交叉检查」或「N 个 agent 并行攻不同模块」的人
- 长任务重构期间还想并行修紧急 bug,不想 stash 来回折腾
- 用 Claude Code / Codex 等终端 agent、习惯一个 agent 占一个终端的人
- 受够了
git stash/ 频繁切分支导致 agent 上下文错乱的开发者
为什么是 worktree,不是 clone 或 stash
| 方案 | 问题 |
|---|---|
| 同一目录切分支 | agent 跑到一半你切分支,它的文件状态全乱;两个 agent 抢分支 |
git stash | 临时切走再切回,agent 看到的代码状态不连续,容易误判 |
多次 git clone | 每个 clone 是独立仓库,分支/对象不共享,磁盘翻倍,push/pull 各管各 |
git worktree | 一个仓库共享 .git 对象,多个工作区各占一个目录、各在一个分支,互不干扰 |
worktree 共享同一份 .git(对象、refs、配置),所以磁盘开销小、分支全局可见,但每个工作区的文件系统状态和当前分支是独立的——正好是并行 agent 需要的隔离。
第一步:建工作区布局
推荐把主仓库和各 worktree 放在同级目录,命名带上任务语义:
# 假设主仓库在 ~/code/myapp(在 main 分支)
cd ~/code/myapp
# 为每个并行任务建一个 worktree + 新分支
git worktree add ../myapp-feature-auth -b feature/auth
git worktree add ../myapp-bugfix-payment -b bugfix/payment
git worktree add ../myapp-refactor-api -b refactor/api-client
# 查看所有 worktree
git worktree list
得到的目录结构:
~/code/
├── myapp/ # 主仓库,留在 main 做 review/合并
├── myapp-feature-auth/ # Agent A 在这里跑,feature/auth 分支
├── myapp-bugfix-payment/ # Agent B 在这里跑,bugfix/payment 分支
└── myapp-refactor-api/ # Agent C 在这里跑,refactor/api-client 分支
基于已有分支建 worktree(不新建分支):
git worktree add ../myapp-hotfix existing-branch
第二步:每个工作区开一个 agent
每个 worktree 是完整的工作目录,进去直接开 agent:
# 终端 1
cd ~/code/myapp-feature-auth && claude
# 终端 2
cd ~/code/myapp-bugfix-payment && claude
# 终端 3
cd ~/code/myapp-refactor-api && codex
每个 agent 看到的是自己分支的干净状态,改文件、跑测试、commit 全在自己的工作区,不会碰到别的 agent 的改动。
第三步:依赖与构建产物隔离(关键坑)
worktree 共享 .git,但不共享 node_modules / .venv / 构建缓存——这些是工作区本地的。两个注意点:
- 每个 worktree 要各自装依赖:
cd ~/code/myapp-feature-auth && pnpm install
cd ~/code/myapp-bugfix-payment && pnpm install
- 端口 / 数据库 / 缓存别撞车:如果多个 agent 各自起 dev server,端口要错开(如 3000 / 3001 / 3002);用本地数据库或 SQLite 的项目,确认各 worktree 不写同一个库文件。
本站经验(aiho.net):
@nuxt/content的 SQLite 内容库是 build 时生成的本地文件,两个 worktree 同时 build 会互相覆盖导致no such table。并行时要么错开 build,要么确认各自有独立的.data/.nuxt目录(worktree 天然隔离这些,因为它们不在 git 跟踪里)。
第四步:合并回主干
agent 在各自分支 commit 后,回主仓库走正常 review/merge:
cd ~/code/myapp # 主仓库,main 分支
git fetch # 如果 worktree 已 push 到远端
# 本地合并(worktree 的 commit 在共享 .git 里,本地直接可见)
git merge feature/auth
# 或更推荐:走 PR,让另一个 agent 或人 review
# 解决潜在冲突——并行改动重叠时这里会暴露
推荐:每个 worktree 的分支单独开 PR,用「一个 agent 写、另一个 agent 审 diff」的模式(见 终端 agent 工作流),人做最终 merge。
第五步:用完清理
# 删除某个 worktree(先确认改动已合并/push)
git worktree remove ../myapp-feature-auth
# 如果目录已手动删了,清理悬挂记录
git worktree prune
# 删掉已合并的分支
git branch -d feature/auth
常见踩坑
- 同一分支不能在两个 worktree 同时 checkout:git 会拒绝。每个 worktree 必须在不同分支——这正是隔离的保证。
- 忘了各装依赖:新 worktree 没有
node_modules,agent 一跑就报 module not found。建 worktree 后第一件事是装依赖。 - dev server 端口/数据库撞车:并行起服务要错开端口,共享本地库要小心写冲突(见第三步本站经验)。
- 改了
.git/config全局生效:worktree 共享配置,改 user.email、remote 等是全局的,别以为是本工作区私有。 - 路径写死:有些工具/脚本把绝对路径写死在配置里,换到 worktree 目录会失效,用相对路径或环境变量。
- agent 跨工作区找文件:给每个 agent 的项目记忆(CLAUDE.md 等)里写清「你只在当前目录工作,不要去别的路径」,避免它顺着文件系统乱翻。
- 删 worktree 前没合并:
git worktree remove会丢掉未提交的改动,删之前确认 commit 已 push 或合并。
进阶:脚本化批量开 worktree
#!/usr/bin/env bash
# spawn-agents.sh —— 一键为多个任务开 worktree + 装依赖
set -euo pipefail
tasks=("feature/auth" "bugfix/payment" "refactor/api-client")
for t in "${tasks[@]}"; do
dir="../myapp-${t//\//-}" # 把 / 换成 -
git worktree add "$dir" -b "$t"
( cd "$dir" && pnpm install )
echo "ready: $dir ($t)"
done
git worktree list
什么时候不该用 worktree
worktree 不是万能的并行方案,以下三类场景它反而添乱:
| 场景 | 为什么不适合 | 替代做法 |
|---|---|---|
| 几个任务改的是同一批文件 | worktree 只能隔离目录,隔离不了合并冲突——冲突会全部堆到 merge 那一步 | 串行做,或一个 agent 先改完另一个再接 |
| 项目装依赖极慢 / 需要重编译 | 每个 worktree 都要各装一遍依赖,开 4 个工作区的成本可能高于收益 | 先只开 2 个,或复用构建缓存 |
| 任务之间有严格先后依赖 | 并行的前提是任务独立,有依赖就退化成等待 | 拆到能独立为止,否则串行 |
并行度怎么定:从 2 个开始。本 playbook 的经验是——并行度的瓶颈通常不是机器,而是你的 review 能力;开 5 个 worktree 意味着你要审 5 个 PR,审不过来就是纯负债。
2026-10-24 更新:Claude Code v2.1.309 一次性补了三条 worktree 隔离绕过
如果你依赖「worktree 隔离 = 安全边界」这个假设,这一版必须升。 官方 CHANGELOG(tag v2.1.309,published_at 2026-10-22T22:18:57Z,prerelease: false)中,与本文主题直接相关的三条:
| 修复项 | 含义 |
|---|---|
| worktree 隔离会话接受了一些 locale 前缀命令 | 隔离守卫本应拒绝,实际放行了 → 隔离被绕过 |
| worktree 隔离会话在 zsh 上接受了一些算术命令 | 同上,且是 shell 相关的绕过 |
| Claude Code 创建的 worktree 与分支检出会忽略 git replace refs | 与它自己的其他 git 操作口径不一致,可能造成你看到的提交历史和实际不一致 |
同一版还修了两条沙箱侧问题,同样影响隔离假设:
- macOS / Linux 上,沙箱化 Bash 命令会在沙箱之外运行 shell 的启动文件(每条命令前都跑一次);
- macOS 沙箱的
denyWriteglob,在通过符号链接到达该路径时不会作用于真实位置——符号链接是沙箱规则的常见绕行路径。
对本文读者的行动建议:① 把 Claude Code 升到 v2.1.309+ 再依赖 worktree 隔离;② 不要把 worktree 隔离当成唯一的安全边界——它是「防止并行互相干扰」的工程手段,不是沙箱;涉及不可信输入的场景,仍然要跑在真正的容器 / 沙箱里(参见 Agent 沙箱);③ 符号链接要特别小心,本目录布局里若有 symlink,升级后请复测一次 deny 规则是否真的生效。
口径说明:本站沿用既有纪律——官方 CHANGELOG 的版本标题下不标注发布日期;上文的
2026-10-22T22:18:57Z取自 GitHub Releases API 的 tag 时间戳,非厂商公布发布日,如与官方口径冲突以官方为准。
2026-10-31 更新:v2.1.314 又补掉一条 worktree 沙箱绕过,并给出可拒绝的写入边界
与本文直接相关的一条:官方 Release Notes(tag v2.1.314,2026-10-30T01:06:26Z,prerelease: false)原文 "Fixed sandbox protections not applying to a worktree entered by claude -p --resume or --continue"。
这条为什么值得单独记:上一节讨论的是 worktree 隔离会话的绕过,本条是另一回事——沙箱保护在「从 claude -p --resume / --continue 进入的 worktree」里根本没生效。二者叠加的含义是:无人值守续跑进的 worktree,此前可能完全不受沙箱约束。用 --resume 做并行编排的,这一版必须升。
同一版还新增了 permissions.blockWritesOutsideWorkingDirectories:开启后 Write / Edit / NotebookEdit 在所有权限模式下都拒绝工作目录之外的路径。它与本文的并行布局有直接交互——多个 worktree 各自是独立工作目录,开启此项后「跨 worktree 写文件」会被拒绝(这正是你想要的隔离效果),但任何依赖 agent 写共享临时目录的编排会直接失败。
行动建议:① 用
claude -p --resume/--continue进 worktree 的,升到v2.1.314;② 想让隔离更强硬的,评估permissions.blockWritesOutsideWorkingDirectories,先确认你的编排是否需要写工作目录外的共享文件;③ 本条与上节一样,worktree 隔离仍只是工程手段,不是沙箱——不可信输入请跑在容器 / 沙箱里(参见 Agent 沙箱)。详见 v2.1.314 资讯。 2026-11-01 复核:上一条里的「升到v2.1.314」已过时——Claude Code 最新 stable 为v2.1.316(tag 时间戳2026-10-31T01:01:35Z,prerelease: false),请改钉v2.1.316。经 Releases(/releases/tags/v2.1.315返回 404)与/tags双端点核对,v2.1.315不存在,序列为…312 → 314 → 316。本版与本文直接相关的一条:🔧 Claude Code 自行退出时遗留的 shell 命令被修(官方原文 "Fixed shell commands being left running on macOS and Linux when Claude Code exits by itself, for example when credentials are refused or a cloud session is archived")——对 worktree 并行编排尤其重要:claude -p因凭据被拒或云会话归档而自行退出时,此前挂在后台的命令会继续跑,多个 worktree 同时泄漏进程会互相抢资源。另新增CLAUDE_CODE_SUBAGENT_EFFORT(子代理不再继承会话 effort),fan-out 派活时可单独设档;网关侧新增managed.policy_mode: layered(每条命中的策略都生效、逐层合并,而不是只取第一条)。
一句话总结
一仓库 → 多 worktree(各占一分支一目录)→ 每区一个 agent 并行干
→ 各装依赖、错开端口 → 分支开 PR → 人工 review + merge → 清理
worktree 把「并行 agent 互相打架」变成「并行 agent 互不可见」,这是多 agent 工作流最便宜也最可靠的隔离手段。
延伸阅读
相关工具
Aider vs Claude Code:终端 AI 编程双雄怎么选
Aider vs Claude Code 2026 选型对比:开源 BYOK 多模型 vs Anthropic 订阅长任务 Agent,从编程能力、多模型支持、价格、Git 集成、国内可用性和适合人群判断,帮你选对终端 AI 编程工具。
Aider vs Continue:终端会话派还是 IDE 自建派?2026 对比
Aider 与 Continue 2026 选型对比:两者都是开源、模型可换的路线,但 Aider 是终端里的 Git-native 会话工具,每次改动自动生成一个 commit;Continue 是 IDE 内的可配置助手,强调自定义与自托管。从 6 个维度给出明确取舍。
Aider vs Crush:CLI pair programmer vs 终端 TUI agent(2026 实测选型)
Aider vs Crush 2026 选型对比:Git 原生 AI pair programmer vs Charmbracelet 终端 TUI agent。从工作哲学、多模型、Git 集成、LSP/MCP、价格和国内可用性帮你选对终端 AI 编程工具。
Cursor vs Aider:GUI IDE 还是 CLI?2026 对比
Cursor vs Aider 2026 选型对比:GUI IDE vs Git 原生 CLI,从 Composer vs Architect 双模型、Tab 补全、多模型 BYOK、价格计费、开源与否和适合人群判断,帮开发者选对。Cursor 是闭源 VS Code fork 月费 $20,Aider 是开源 Apache-2.0 CLI 自带 API key。
Aider vs OpenCode:两个开源终端 Agent,选哪个?2026 对比
Aider 与 OpenCode 2026 选型对比:同为开源终端 agent,Aider 以 Git-native 工作流与多语言支持见长,OpenCode 主打模型无关与 TUI 体验。从 6 个维度给出取舍建议。
Claude Code vs Cline:CLI AI Agent 怎么选?2026 对比
Claude Code vs Cline 2026 选型对比:Anthropic 官方闭源 CLI Agent vs Apache-2.0 开源 VS Code 插件。从模型绑定、工作流、MCP 支持、价格、隐私和适合人群 6 个维度帮你选对 CLI AI 编程工具。
AI 编程工具选型决策树:30 个场景告诉你该用哪个
整合 AI 之家 11 篇深度评测:按角色、预算、规模、网络环境四维度的 AI 编程工具决策树,Cursor / Claude Code / Aider / Trae 等主流工具一图选型,附 30 个场景表。
2026 年 AI 编程工具全景图:18 款实测排行
2026 年 AI 编程工具全景:18 款实测按 IDE / CLI / 插件 / Agent / Builder / 本地分桶,给出 Top 10 排行、5 维评分方法论,以及国内 / 海外 / 学生党的选型建议。
Aider 深度评测:把 AI 编程当 git 工作流的极客派最爱
Aider 深度评测:git-native 心智的真实代价、Architect 双模型经济学、与 Claude Code 的决策边界、何时不该选 Aider。AI 之家 编辑部基于官方文档与社区公开反馈整合,非厂商付费内容。