Git worktree:让多个 Agent 并行干活不打架
- 理解为什么多 Agent 并行会产生文件冲突,以及 worktree 的解法原理
- 能用 git worktree add / list / remove 实际创建和管理多个工作目录
- 掌握"一个 worktree 一个 Agent"的并行开发分工方案
- 学会把各 worktree 分支合并回主干,以及碰到常见坑时怎么排查
想让两个 AI Agent 同时干活,结果发现它们在同一批文件上打架——一个刚写完 auth.ts,另一个已经把同名文件改成了另一个版本。最后 git 一 merge,冲突一大片,手动解完还不如一个一个来。
这不是 Agent 的问题,是工作流的问题。git worktree 就是那个解药。
问题出在哪:多 Agent 为什么会打架
AI 编程工具 一个让人兴奋的能力是可以同时开多个会话、并行推进不同任务。但默认情况下,所有会话都在同一个工作目录操作文件——它们共享同一套文件,写入时互相覆盖。
具体踩过的坑大概长这样:
- 同一个文件被两个 Agent 并发修改:Agent A 在改
api/user.ts,Agent B 也在改api/user.ts,谁后保存谁赢,前面那个白改了。 - 分支切换互相干扰:你给 Agent A 创建了
feature/auth分支,中途给 Agent B 切了feature/refactor,A 的文件上下文瞬间乱掉。 - 依赖安装冲突:两个 Agent 同时跑
npm install,写package-lock.json时互相踩,最终 lock 文件损坏。
这几个坑的根源都一样:多个 Agent 共享同一个工作目录。
worktree 是什么,怎么解这个问题
git worktree 是 git 内置的功能(不是插件,也不需要装额外工具)。它的核心能力是:从同一个仓库,checkout 出多个独立的工作目录,各自关联不同的分支,但共享同一个 .git 对象库。
用一个类比:原来你只有一张桌子,所有人挤在上面干活;worktree 相当于给每个人开了一张独立的工作台,但大家共用同一个材料库(.git 目录)。桌子互不干扰,材料只存一份。
对 AI 并行开发来说,这意味着:
- 每个 worktree 是一个独立的物理目录,文件互不影响。
- 每个 worktree 关联独立的分支,切换不会影响其他 worktree。
- 所有 worktree 的提交最终都在同一个
.git里,合并非常自然。
可跑命令:add / list / remove
创建一个新 worktree
# 语法:git worktree add <目录路径> <分支名>
git worktree add ../my-project-auth feature/auth
你应该看到什么:
Preparing worktree (new branch 'feature/auth')
HEAD is now at a1b2c3d feat: init project
然后 ../my-project-auth 目录就存在了,里面是完整的项目文件,关联到 feature/auth 分支。进去就能直接干活:
cd ../my-project-auth
# 启动 Claude Code 或其他 Agent,它只在这个目录里操作
claude
如果分支已经存在,直接用分支名;如果想从已有分支创建 worktree:
# 基于远程分支创建本地 worktree
git worktree add ../my-project-refactor -b feature/refactor origin/main
查看当前所有 worktree
git worktree list
你应该看到什么:
/home/user/my-project a1b2c3d [main]
/home/user/my-project-auth b2c3d4e [feature/auth]
/home/user/my-project-refactor c3d4e5f [feature/refactor]
第一行是主工作目录,后面是你创建的 worktree。每行显示路径、当前 commit hash 和分支名。
删除一个 worktree
# 先删目录,再清理 git 记录
git worktree remove ../my-project-auth
如果目录里有未提交的修改,git 会拒绝删除并提示。强制删除:
git worktree remove --force ../my-project-auth
删完之后做一次清理,移除 .git 里的过期引用:
git worktree prune
建议养成习惯:任务完成、分支合并后立刻 remove + prune,不然时间久了 worktree 越堆越多,git worktree list 一翻一大串废弃的目录。
怎么配合 AI 并行开发
分工的基本原则:每个 Agent 对应一个 worktree,每个 worktree 对应一个分支,任务之间依赖关系越弱越好。
实际项目里常见的三路并行方案:
my-project/ ← 主目录,你在这里统筹、做 code review
my-project-refactor/ ← Agent A:重构旧模块(不碰新功能文件)
my-project-feature/ ← Agent B:开发新功能(不碰旧模块)
my-project-bugfix/ ← Agent C:修线上 bug(基于当前 main)
给 Claude Code 这类 Agent 分配任务时,明确告诉它"你只在 my-project-refactor 目录下操作",大多数 Agent 会遵守当前工作目录的边界。
这个模式背后的逻辑和 subagent 拆解并行任务 的思路是一致的——把任务切成独立的、边界清晰的块,每块交给一个 Agent,最后汇总。worktree 给了这个思路一个文件系统层面的物理隔离保障。
配合大型代码库的注意点:如果你用的是 monorepo,各 worktree 共享同一个 node_modules 会出问题(见下方坑位)。大型 monorepo 的 worktree 策略可以参考 大型代码库策略 4.7。
合并回主干的流程
各个 worktree 的任务完成后,标准的合并流程:
# 1. 在 worktree 目录里,确认改动、提交
cd ../my-project-feature
git add .
git commit -m "feat: 新功能完成"
# 2. 回到主目录
cd ../my-project
# 3. 合并分支(选一种方式)
git merge feature/new-feature # 普通 merge,保留分支历史
git merge --squash feature/new-feature # squash merge,压成一个 commit
# 4. 删除 worktree 和分支
git worktree remove ../my-project-feature
git branch -d feature/new-feature
git worktree prune
如果多个 worktree 改了共同依赖的文件(比如 package.json、共用的 utils 函数),合并时会有冲突,这是正常的——说明你的任务拆分没有做到完全独立。解冲突和普通 merge 冲突一样处理,没有特殊的地方。
SDD 规范驱动流程 里的 Specify 阶段就是要在任务开始前把边界说清楚,同样的道理在这里也适用:分配任务前明确哪些文件归哪个 Agent 管,合并时冲突会少很多。
故障排查表
| 症状 | 原因 | 解法 |
|---|---|---|
fatal: 'feature/xxx' is already checked out |
该分支已被另一个 worktree 占用,一个分支同时只能被一个 worktree 使用 | git worktree list 查看哪个 worktree 在用,换一个新分支名,或先 remove 占用的 worktree |
worktree 目录存在但 git worktree list 里没有 |
手动删了目录但没运行 remove,git 引用残留 |
git worktree prune 清理过期引用 |
npm install 在 worktree 里报错或行为怪异 |
多个 worktree 共享了同一个 node_modules 目录,各 worktree 依赖版本不一致时互相踩 |
在 worktree 目录里独立运行 npm install,或用 --prefix 指定各自的安装目录;monorepo 场景考虑用 pnpm workspaces 做隔离 |
| merge 时出现大量冲突 | 多个 worktree 修改了同一个文件(通常是共用 utils 或配置文件) | 合并前 git diff main...feature/xxx -- 共用文件 先看差异量;任务分配阶段就要划清文件边界 |
| worktree 里的 Agent 改了主分支的文件 | Agent 没有遵守工作目录边界,或者任务描述里没有限制路径 | 重新给 Agent 的 prompt 加上明确的目录限制;用 git hooks 或 Claude Code 的权限配置限制可操作路径 |
git worktree remove 失败,提示有未提交修改 |
worktree 里有改动未 commit | 先 commit 或 stash,或用 --force 强制删除(会丢失未提交内容) |
常见问题
Q:worktree 和直接 clone 多份仓库有什么区别?
clone 多份会完整复制 .git 对象库,磁盘占用是几倍关系,而且各副本的提交互相独立,合并需要走 remote。worktree 共享同一个 .git,磁盘只多了工作文件,合并就是本地 merge,快很多。多数情况下 worktree 是更好的选择。
Q:worktree 里可以直接 git checkout 换分支吗?
不建议。worktree 的设计是每个目录固定关联一个分支。如果要换分支,正确的做法是 git worktree remove 删掉这个 worktree,再 git worktree add 新建一个关联新分支的。在 worktree 里强行 checkout 容易造成引用混乱。
Q:一个仓库最多能开多少个 worktree?
git 没有硬性上限。但实际上,worktree 的价值在于并行隔离,开太多反而难管理。根据经验,同时活跃的 worktree 超过 4-5 个,统筹成本会明显上升。按任务数量而不是"越多越好"来开。
Q:CI/CD 环境里能用 worktree 吗?
可以,而且很有用。在 CI 里可以用 worktree 并行跑不同分支的构建任务,而不需要多次 clone 整个仓库。具体用法取决于你的 CI 工具,概念是一样的。
Q:worktree 删掉后,里面的提交会丢吗?
不会。git worktree remove 只是删掉工作目录和 git 里的 worktree 引用,分支和它上面的 commit 依然存在。你随时可以 git checkout feature/xxx 切到那个分支,或者重新 git worktree add 还原工作目录。
👉 看看我们的 AI 编程实战体系课,或逛 AI 编程教程大全 把基本功打扎实。