AI 时代你不能不知道的 git worktree

git worktree 这个命令 2015 年就有了,比我用的任何 AI 编程工具都老。但它直到我开始用 AI 替我写代码,才真正显出价值:多个分支、多个人(或多只 Agent)能在同一份仓库历史里并行干活,各自有独立的工作目录,互不踩脚。

引子:你的 Agent 正在和你抢同一份工作目录

你大概率遇到过这个画面。

正在 main 上改功能,改到一半,突然想起有个线上 bug 要修。顺手开了个 AI Agent(Cursor、Claude Code、WorkBuddy 都行),让它「去把登录验证码失效的 bug 修了」。它很听话,直接在你当前目录里切到 fix 分支、改文件、跑测试。等你回过神,刚才那一半没提交的功能改动已经被它搅进去了。

更常见的另一种:想让两个 Agent 同时干活,一个重构旧模块,一个给新功能补测试。但它们都在同一个工作目录里,第二个一启动就把第一个的活儿冲掉。最后只能排队等,串行跑,一天被拉成三天。

这真不怪你,是「一个仓库只有一个工作目录」这个老设定在拖累。

worktree 到底是个啥

普通的 git checkout 是在同一个目录里切换分支,任何时候你只能看见一个分支的文件。

git worktree 反过来,给任意分支再开一个独立目录,多个目录挂在同一份 .git 历史上,各自有各自的文件状态。

bash 复制代码
~/code/
├── lumen/             # 主工作树,分支 main
│   └── .git/          # 唯一的 git 目录(对象数据库在这)
├── lumen-dashboard/   # 关联工作树,分支 feat/analytics-dashboard
└── lumen-login-fix/   # 关联工作树,分支 fix/login-captcha

三个目录共享同一份提交历史,都连着同一个 .git 对象数据库,但文件各是各的。你在 lumen-dashboard 里改 Dashboard.tsxlumen 里的 Dashboard.tsx 纹丝不动。

用法和正常 checkout 没区别:改文件、commit、push 照常。区别在于你再也不用反复 checkout + stash 来「保存现场」了。

传统分支 vs worktree

过去想并行搞两件事,套路是这样的:

perl 复制代码
git stash              # 先把当前活儿塞起来
git checkout fix       # 切过去修 bug
... 修完 ...
git checkout feat      # 切回来
git stash pop          # 再把现场捞回来(祈祷没冲突)

生产 bug 一打进来,心流就碎了。stash 攒多了根本记不住哪坨对应哪件事,切错分支把代码提交到地方更是常事。

用 worktree,你直接为 bug 开个新目录,主目录啥都不动:

bash 复制代码
# 把已存在的分支挂成一个工作树
git worktree add ../lumen-login-fix fix/login-captcha

# 或者一步到位:新建分支 + 开工作树
git worktree add -b feat/analytics-dashboard ../lumen-dashboard

新目录生成在主项目同级的位置,checkout 到你指定的分支。之后每个目录里独立编辑、提交、push,主工作目录干净如初。

有个限制得先说清楚:同一个分支不能同时挂在两个 worktree 上,每个 worktree 必须 checkout 一个唯一分支。这反而逼出了「一个任务 = 一个分支 = 一个目录」的对应关系,脑子不容易乱。

AI 时代它才好用

下面这几条,是写给已经开始用 AI 写代码的你。

给每只 Agent 一个房间。 最直白的玩法:每个 AI 任务开一个工作树,把 Agent 关进那个目录跑。

bash 复制代码
git worktree add -b agent/dashboard ../lumen-dashboard
git worktree add -b agent/login-fix  ../lumen-login-fix

Agent A 在 lumen-dashboard/ 里搭看板,Agent B 在 lumen-login-fix/ 里修登录验证码,主目录 lumen/ 留在 main,你随时 git diff 审阅两边,或者自己手写点不想让 Agent 碰的精细活。两个 Agent 用的是同一份 Git 历史,但文件系统互不干扰。A 把 Dashboard.tsx 改崩了,绝不会连累 B,更不会动你的主树。

主树始终是能发的状态。 Agent 跑起来经常吐一堆中间产物、临时脚本、调试日志。它在主目录里跑,你的 git status 就被污染,连「这棵树现在能不能发」都看不清。关进 worktree 后,主树一直是你亲手维护的干净状态,Agent 那边折腾成什么样都不影响你随时合代码、切分支、跑 CI。

你的 IDE 不被打断。 不少 Agent 会改 .vscode/、临时装依赖、甚至动 package.json。它在你正在用的目录里跑,编辑器就疯狂弹「文件已变更」,终端里 npm 进程互相打架。worktree 把这一切挪到另一个目录,IDE 稳如老狗,该干嘛干嘛。

实战:线上登录挂了,让 Agent 救火,你继续写看板。 初始布局就一个主树:

bash 复制代码
~/code/
└── lumen/           # 主工作树,main

你正在 lumen/ 里搭数据看板(还没提交),告警群炸了,登录验证码失效,用户进不来。开个修复工作树,把救火 Agent 丢进去:

bash 复制代码
cd ~/code/lumen
git worktree add -b fix/login-captcha ../lumen-login-fix

布局变成:

bash 复制代码
~/code/
├── lumen/             # 主工作树,main(你继续搭看板)
└── lumen-login-fix/   # Agent 在这里修登录验证码

接下来:让 Agent 在 lumen-login-fix/ 里定位、修复、跑测试;你自己在 lumen/ 里继续推进看板,完全不被打断;等 Agent 修完,你 cd 过去 git diff 验收,满意了回主树 git merge fix/login-captcha

任务被中断时,你不再需要 stash 救命,只是开了个新房间。

操作速查

看当前有哪些工作树。 动手删之前先看清楚 Git 认得哪些:

复制代码
git worktree list

输出类似:

css 复制代码
/Users/you/code/lumen            66c16256 [main]
/Users/you/code/lumen-dashboard  0c8ba118 [feat/analytics-dashboard]
/Users/you/code/lumen-login-fix  a16e4be2 [fix/login-captcha]

一眼能看出哪个分支挂在哪个目录,省得去复用已经被某个 worktree 占用的分支。

把工作树合并回主分支。 合并逻辑和普通 Git 一样,只是上下文更清楚,每个分支都住自己目录里:

bash 复制代码
# 1. 在 feature 工作树里改完、提交
# 2. 切回主工作树
cd ../lumen && git checkout main
# 3. 合并
git merge feat/analytics-dashboard
# 4. 解决冲突、push

每个 worktree 只服务于一个分支,你几乎不可能提交错分支,hotfix 打断 feature 时也不会丢现场。

删掉一个工作树。 用完就清:

arduino 复制代码
git worktree remove ../lumen-dashboard

只删工作目录,分支还在。要求工作树是干净的(无未提交改动、无未跟踪文件),强删加 --force。主工作树不能被 remove。删之前务必在对应工作树里 git status 确认没有未提交改动,不然容易把 Agent 的劳动成果弄丢。

清理孤儿元数据。 手贱直接 rm -rf 删了工作树目录,Git 在 .git/worktrees/ 下还留着元数据,git worktree list 会标 missing。清掉这些僵尸记录:

复制代码
git worktree prune

只清很久没用的,加过期时间:

css 复制代码
git worktree prune --expire 7.days.ago

本地环境想一次清干净所有僵尸:git worktree prune --expire now

带 Agent 跑的几个坑

  • 同一个分支不能挂两个 worktree。给每个 Agent 单独开分支,命名区分一下,比如都加 agent/ 前缀。
  • 启动 Agent 时把工作目录指对。很多 Agent 默认在当前目录干活,开错房间是最常见的翻车点。
  • 依赖不共享。worktree 是独立目录,node_modules.venv 默认不跟着走。要么软链过去,要么让 Agent 第一步先装依赖,别让它在空目录里瞎跑测试。
  • 明确告诉 Agent 只动当前目录,别顺着相对路径去碰兄弟工作树或主树。
  • Agent 干完你亲自 diff 看一眼再合。worktree 只解决隔离问题,AI 写的要不要进主干,决定权在你。

结语

我用了好几年 Git 才发现 worktree。在 AI 编程之前,它只是偶尔并行两个 feature 的小技巧;AI 编程普及之后,它成了多 Agent 并行开发的底子。谁先把它用顺,谁就能让好几只 Agent 同时给自己打工,主分支还一直干净、能发、能审。

顺序的简单活儿,普通分支切换够用。但凡你冒出「要能同时在两个地方」的念头,不管是两个 Agent 还是 Agent 加你自己,worktree 就是那个答案。去开个房间,把 Agent 关进去。

相关推荐
观测云29 分钟前
AI时代的用户访问监测:观测云带你身临其境体验用户与前端UI交互旅程
前端·可观测性·观测云·rum
CoderYanger36 分钟前
A.每日一题:输入单词需要的最少按键次数 Ⅰ+Ⅱ
java·数据结构·算法·leetcode·面试
Cosolar39 分钟前
一文弄懂 Agent Harness 与 Agent Runtime 的区别
java·后端·github
喵本喵叁肆40 分钟前
06-M6-部门过滤与综合研判-从问答机到研判助手
前端·javascript·jquery
长大19881 小时前
Python代码慢?这5个性能优化技巧让速度提升100倍
后端
超超不吵吵1 小时前
Java AI转型实战(十):Agent 智能体初探
后端
TomEval1 小时前
【Web UI 自动化】05 - KDT 模式原理与实现
前端·ui·自动化
南雨北斗2 小时前
vue3项目状态持久化方案Pinia
前端
步行cgn2 小时前
@AllArgsConstructor 是 Lombok 提供的注解
后端