一文搞懂 Git Worktree:多个 AI Agent 同时改代码,如何避免互相打架?
一、为什么 Agent Teams 还需要 Worktree?
上一篇文章介绍了 Agent Teams:通过组建多个 Agent,让它们分工协作、并行执行任务,并通过消息机制互相沟通。
但这里有一个问题:多个 Agent 如果同时修改同一个项目,会发生什么?
假设我们让三个 Agent 开发一个网站:
- Frontend Agent:负责前端页面。
- Backend Agent:负责后端接口。
- Test Agent:负责测试代码。
看起来分工明确,但如果前端和后端 Agent 都需要修改 package.json 呢?
它们可能同时写入文件,导致其中一个 Agent 的修改被覆盖。即使没有同时写入,一个 Agent 也可能读到另一个 Agent 尚未完成的代码。
这就产生了文件冲突问题。
当然,我们可以通过通信,让 Agent 提前商量好谁负责哪些文件。
但实际项目中的文件依赖往往非常复杂,不可能保证它们永远不会修改同一个文件。
有没有一种更直接的解决办法?
有!给每个 Agent 分配一套独立的工作目录,让它们各改各的,最后再统一合并。
这就是 Git Worktree 的作用。
二、什么是 Git Worktree?
首先要明确:Git Worktree 本身不是 AI 技术,而是 Git 原生提供的一项功能。
正常情况下,一个 Git 仓库对应一个工作目录。
假设你正在 feature-a 分支开发功能,突然需要切换到 main 分支修复 Bug。
通常你需要先保存当前修改,再切换分支。
但 Git Worktree 提供了另一种方式:
在同一个 Git 仓库下,创建多个相互独立的工作目录。
例如:
Git 仓库(共享版本历史)
│
├── main/ 主工作目录
│
├── frontend/ 前端工作目录
│
└── backend/ 后端工作目录
这些目录具有三个特点:
- 文件独立:每个目录拥有自己的工作文件,修改互不覆盖。
- 历史共享:共享同一个 Git 仓库的版本历史,不需要重复克隆整个仓库。
- 分支独立:不同目录可以同时在不同分支上开发。
可以把它理解为:
同一份项目,开了多个独立的工作台。
每个人在自己的工作台上修改代码,不会直接影响其他人的文件。
最后再通过 Git,将不同工作台的成果合并起来。
三、为什么 Worktree 特别适合 AI Agent?
人类开发者通常不会在同一时刻操作多个工作目录。
但 AI Agent 不一样。
借助 Agent Teams、SubAgent 等机制,我们可以让多个 Agent 同时执行任务。
如果它们共享一个工作目录,就可能出现三个问题:
1. 文件写入冲突
两个 Agent 同时修改一个文件,可能造成修改覆盖。
2. 读取未完成的代码
Agent A 正在重构一个函数,Agent B 恰好读取这个函数,结果得到尚未完成的代码。
3. 工作环境互相影响
Agent A 修改了项目配置或依赖文件,导致 Agent B 的测试突然失败。
而 Worktree 的解决思路非常简单:
既然共享目录容易产生冲突,那就让每个 Agent 使用独立目录。
例如:
Main Agent
│
分配任务,协调开发
│
┌───────────┴───────────┐
│ │
Frontend Agent Backend Agent
│ │
Worktree A Worktree B
│ │
修改前端 修改后端
│ │
└───────────┬───────────┘
│
Git 合并
│
最终代码
这样,即使两个 Agent 都需要修改 package.json,它们也只会修改自己目录中的那一份文件。
最后通过 Git 合并修改。
需要注意:Worktree 只是隔离了修改过程,并没有消除最终的合并冲突。
如果两个 Agent 修改了同一段代码,合并时仍然可能发生冲突。
但相比运行过程中互相覆盖文件,合并阶段的冲突更容易发现和处理。
四、在 Claude Code 中如何使用 Worktree?
Claude Code 已经支持使用 Worktree 隔离工作目录。
最简单的方法,就是在启动时添加 --worktree 参数。
例如,在一个已有提交记录的 Git 项目中执行:
claude --worktree frontend
Claude Code 会创建一个独立 Worktree,并在其中启动会话。
默认情况下,目录位于:
.claude/worktrees/frontend/
你可以再打开一个终端,执行:
claude --worktree backend
这样就有了两个独立的 Claude Code 会话。
它们可以同时修改项目,却不会直接覆盖对方工作目录中的文件。
1. 与 SubAgent 配合
Worktree 也可以与 SubAgent 配合使用。
例如,在自定义 SubAgent 的配置中添加:
isolation: worktree
这样,子 Agent 执行任务时就可以使用独立的 Worktree。
这意味着 SubAgent 不仅拥有独立的上下文,还能够拥有独立的文件空间。
特别适合代码重构、功能开发等需要修改大量文件的任务。
2. 与 Agent Teams 配合
对于 Agent Teams,同样可以采用 Worktree 隔离的协作思路。
例如,让负责前端、后端的不同 Agent 会话分别在自己的 Worktree 中开发,最后统一整合。
不过,Agent Teams 不等于 Worktree,创建团队也不代表一定会自动为每个成员分配独立目录,需要根据具体工作方式配置。
3. 工作完成后怎么办?
Worktree 中的代码不会因为任务完成,就自动合并回主分支。
通常需要:
- 检查各个 Agent 的代码修改。
- 提交需要保留的修改。
- 通过 Git 合并分支,并解决可能出现的冲突。
- 运行测试,确认整合后的功能正常。
Claude Code 对部分 Worktree 提供自动清理机制,但有未保存的工作成果时,需要先确认如何处理,避免误删。
五、Worktree 能解决所有问题吗?
当然不能。
Worktree 主要解决的是工作目录层面的隔离,而不是所有形式的冲突。
| 问题 | Worktree 能否解决 |
|---|---|
| Agent 同时修改同一个文件 | 可以避免直接覆盖 |
| Agent 读取其他 Agent 尚未完成的文件修改 | 可以避免直接读取 |
| 不同 Agent 的代码合并冲突 | 不能,需要解决冲突 |
| 不同 Agent 修改接口导致不兼容 | 不能,需要协作与测试 |
| 多个 Agent 占用同一个端口或数据库 | 不能,需要额外隔离 |
例如:
Agent A 把一个函数的返回值从字符串改成了整数。
Agent B 却仍然按照字符串类型调用它。
即使两个 Agent 修改的是不同文件,Git 合并时也可能完全没有冲突。
但程序运行起来,还是可能报错。
这种情况叫作语义冲突。
Worktree 无法理解两个 Agent 的代码在逻辑上是否兼容。
因此,Worktree 不能取代 Agent 之间的通信,也不能代替代码测试。
另外,Worktree 需要额外的磁盘空间,而且通常需要为每个目录单独准备开发依赖。
它也不是 Docker 那样的完整运行环境隔离,更不是安全沙箱。
六、SubAgent、Agent Teams、Worktree 有什么区别?
回顾前面几篇文章,我们其实学习了三种不同层面的机制:
| 技术 | 核心作用 | 主要解决的问题 |
|---|---|---|
| SubAgent | 上下文隔离 | 减少子任务对主 Agent 上下文的干扰 |
| Agent Teams | 多 Agent 协作 | 让多个 Agent 分工、通信、协调任务 |
| Git Worktree | 工作目录隔离 | 避免多个 Agent 直接覆盖彼此的代码修改 |
可以简单理解为:
SubAgent: 让 AI 分头思考。
Agent Teams: 让多个 AI 分工合作。
Worktree: 让不同 AI 在自己的工作目录中干活。
三者解决的问题不同,可以根据需求独立使用,也可以组合使用。
举几个例子:
场景一:让 Agent 阅读代码、总结架构。
只读任务,没有文件修改冲突,通常不需要 Worktree。
场景二:多个 Agent 同时开发不同功能。
如果能够明确划分文件归属,可以先通过任务分工和消息通信协调。
场景三:多个 Agent 需要并行修改代码,而且文件可能重叠。
这时就比较适合使用 Worktree,为不同 Agent 提供独立工作目录。
另外,即使只有一个 Agent,如果你希望它尝试高风险的代码重构,也可以使用 Worktree 隔离实验性修改。
七、总结
Git Worktree 的核心思想其实很简单:
让多个开发者或 AI Agent 在同一个 Git 仓库的不同工作目录里并行开发,最后再通过 Git 整合成果。
它并不是专门为 AI 发明的技术,却非常适合多 Agent 并行开发的场景。
不过,Worktree 并不是万能的。
它解决的是文件层面的相互干扰,而代码合并、逻辑兼容性、测试验证,依然需要 Agent 或开发者处理。
最后记住三个关键词:
SubAgent 管上下文,Agent Teams 管协作,Worktree 管工作目录。
理解这三个概念,也就理解了多 Agent 并行开发中非常重要的几种基础机制。