最近用 oh-my-openagent + opencode 写代码,我越来越确认一件事:AI 时代,git worktree 不是「进阶技巧」,而是「必需品」。
为什么它突然变得重要
git 最基础的心智模型是:一个仓库 = 一份代码,分支是代码的「版本线」,切换分支 = 把工作目录里的代码换成另一个版本。这个模型在「一个人一次只干一件事」的年代够用,但 AI 代理打破了两个前提:
- AI 改代码的速度和破坏力远超人类。 一个 agent 会话,十几分钟就能把一个模块重构成面目全非;不满意再来一轮,又是大改。让它在主分支上反复折腾,改到一半想回去?stash?commit?全是脏状态。
- AI 可以并行开好几个。 同一个仓库,让 agent A 重构登录、agent B 修 bug、agent C 写测试——放在同一个目录里,它们会互相踩:同时改同一个文件、互相杀对方的 dev server、
npm install互相覆盖。这已经不是「代码冲突」,是「工作区冲突」。
worktree 解决的就是这个问题:一个仓库,多个互不干扰的工作目录。
worktree 是什么
一句话:共享同一个 .git 对象库,挂多个工作目录,每个目录检出不同的分支,可以同时 checkout、同时构建、同时跑 dev server。
核心命令就四个:
| 命令 | 作用 |
|---|---|
git worktree add ../feat-ai -b feat/ai-refactor | 新建分支 + 新工作目录 |
git worktree list | 列出所有工作目录 |
git worktree remove ../feat-ai | 移除工作目录 |
git worktree prune | 清理失效的 worktree 记录 |
对象库是共享的,所以磁盘开销很小:除了多一份 working tree,不需要像 git clone 那样再存一份完整历史。
AI 时代我为什么离不开它
1. 并行 agent,物理隔离
这是最大的刚需。我现在跑 AI 任务的固定姿势:
git worktree add ../blog-article -b feat/blog-article # agent 写文章
git worktree add ../blog-theme -b feat/blog-theme # agent 改主题
每个 worktree 里各起一个 astro dev --background(端口记得错开),构建缓存、依赖安装、文件改动全部隔离。agent 之间互相不知道对方存在,自然也不会打架——主目录永远保持干净可发布的状态。
2. 实验随便做,主分支零风险
AI 改代码有个特点:它不知道「这个改动会不会把项目搞坏」,或者说它不在乎——试错成本反正由你承担。以前我的选择是:让它在主分支上试,坏了 git checkout .;或者让它开分支,然后反复 git switch 切来切去,还得跟 stash 搏斗。
现在:每个实验一个 worktree,AI 在里面随便折腾。改坏了?git worktree remove 一删了之,主目录毫发无损。方案 A 和方案 B 想对比?两个 worktree 同时存在,一个跑 A 一个跑 B,肉眼对结果。
3. 任务切换零成本,改一半就放那
人类开发者切任务要 stash、commit、恢复现场;AI 会话更是「重启即失忆」——关掉就什么都没了。worktree 让「改到一半的实验」物理落盘:换个任务,直接去另一个目录;回头想继续,回到那个目录接着改。不需要任何现场恢复操作,因为现场就在那里。
配合 oh-my-openagent 这种支持多供应商配置的工具,我甚至会给不同 worktree 配不同的模型:贵的模型干重构,便宜的快模型干写测试。反正互不干扰。
几个坑
- 一个分支只能被一个 worktree 检出。 想同时在两个目录开同一个分支,不行,会直接报错。每个任务开独立分支,收尾后删分支。
- 收尾要主动 remove。 worktree 不会自己消失,
git worktree list扫一眼,完事的就git worktree remove。忘了也不致命,就是占着目录。 - 构建缓存 / IDE 索引是独立的。 每个 worktree 的
node_modules、.astro、IDE 索引都要各自生成,首次构建会慢一点。这是隔离的代价,值得付。 .git从目录变成了文件。 worktree 里的.git是一个指向主仓库的文本文件,少数工具不认,踩到再说。- 别乱删主仓库目录。 直接删掉主仓库文件夹,所有 worktree 的
.git文件会指向一个不存在的路径,git 直接懵。正确顺序是:先git worktree remove清掉所有 worktree,再删主目录。
什么时候不需要它
说完了好处,也说点诚实的边界:
- 单仓库、单任务、单人:一个分支 + stash 完全够用,worktree 反而是多余的开销——每个目录都要重新生成
node_modules、IDE 索引,首次构建多花时间。 - 巨型 monorepo:依赖安装和构建缓存重复成本会放大很多倍,开 3 个 worktree 等于把构建成本乘以 3。这种场景更值得的做法是只让一个 worktree 跑完整构建,其他的只做文件改动。
- 改一行就完的活:不值得为它建目录。worktree 的收益来自「长时间、大改动、可并行」的 AI 任务,短平快的改动直接在当前分支做。
我的判断标准就一条:如果这个任务失败了我需要一键丢弃且不影响任何其他工作,就开 worktree;否则不开。
写在最后
AI 写代码这件事,真正值钱的不是「AI 帮你写」,而是「你敢让 AI 放手写」。而敢放手的前提,是有一个物理层面的安全网——改坏了随时丢掉重来,并行任务互不干扰。
对我来说,git worktree 就是这个安全网。它让我能放心地同时开三个 agent,让它们各干各的,然后像收麦子一样,把好的合并回来,把坏的连根拔掉。