一句话结论
git worktree 是 Git 自带的能力,不是 AI Coding 工具发明的新东西。
它解决的问题也不是“怎么创建分支”,而是更具体的一件事:同一个仓库,能不能同时展开多个互不干扰的工作现场。
以前我们常说“开个分支做需求”。但分支只是 Git 历史上的一个指针,它不会给你第二个工作目录。你在一个目录里切分支,文件、依赖、编辑器状态、未提交改动都会跟着变化。
worktree 多给你的是一个真实目录:
repo/ # 主工作区
repo-hotfix/ # hotfix 分支的工作区
repo-ai-refactor/ # AI 重构实验的工作区
repo-review-pr-123/ # PR review 的工作区
这些目录不是几份完全独立的 clone。它们共享同一个 Git 仓库的对象数据和历史记录,但每个目录有自己的文件现场、HEAD、index 和当前 checkout。
所以 worktree 最适合的不是“单线程写代码”,而是:
- 当前工作不能被打断;
- 需要快速切到 hotfix;
- 想同时 review 几个分支;
- 想让 AI agent 并行尝试多个方案;
- 想把一个高风险改动关在临时目录里,做完再决定要不要合并。
如果只记一句话:
branch 保存不同方向的历史,worktree 同时展开这些方向的现场。
先把 branch、checkout、worktree 分开
Git 里有几个概念很容易混在一起。
branch 是一个名字,指向某个 commit。比如 main、feature/login、hotfix/payment-timeout。
checkout 是把某个 branch 或 commit 变成当前工作目录里的文件状态。
worktree 是一个真实的工作目录。一个 Git 仓库可以有一个主 worktree,也可以有多个 linked worktree。linked worktree 看起来像另一份代码目录,但它背后仍然挂在同一个 Git 仓库上。
默认的 Git 使用方式大概是:
一个仓库
-> 一个工作目录
-> 同一时间 checkout 一个分支
用了 worktree 后变成:
一个仓库
-> 多个工作目录
-> 每个目录 checkout 不同分支或 commit
这就是它和普通分支的区别。
分支解决的是版本历史分叉;worktree 解决的是工作现场并行。
它和重新 clone 一份有什么区别
很多人在不知道 worktree 之前,会用多 clone 解决并行问题:
app/
app-copy/
app-hotfix/
这当然能用,但成本偏高。
多 clone 意味着每个目录都有一套 .git 对象库、远程信息、hooks、配置和引用。大仓库会占更多磁盘;同步远程分支、清理本地分支、保持配置一致也更烦。
worktree 更像“轻量多开”:
同一个 Git 仓库对象库
-> 多个工作目录
-> 每个工作目录有自己的 checkout 状态
它不是完全免费的。每个 worktree 仍然会有一份真实文件,也通常会有自己的依赖目录,比如 node_modules、.venv、target、dist。但 Git 历史和对象数据不会完整复制一遍。
所以三种方式可以这样理解:
| 方式 | 适合 | 主要问题 |
|---|---|---|
| 切分支 | 单任务、短切换 | 未提交改动和编辑器上下文容易被打断 |
| 多 clone | 强隔离、偶发需求 | 占空间,配置和远程状态容易分散 |
| worktree | 多任务并行、AI 实验、hotfix、review | 需要管理目录、依赖和分支占用 |
为什么 AI Coding 特别适合 worktree
AI Coding 改变了开发节奏。
传统开发常常是一条线:我在一个分支上理解问题、改代码、跑测试、提交 PR。即使中途切换任务,切换频率也不会太夸张。
AI agent 的工作方式更像并行探索:
- 同一个需求可以让 agent 尝试两种实现;
- 一个后台任务可以继续修测试,前台人类继续写设计;
- 一个 agent 可以做重构,另一个 agent 可以查 bug;
- 一些尝试最后会被丢弃,只保留最好的方案。
如果这些都发生在同一个工作目录里,文件很快会互相污染。你会分不清哪个改动来自哪个任务,也很难只回滚其中一个方案。
worktree 给 AI agent 的价值正好在这里:每个任务一个目录,每个目录一份 diff,每个 diff 单独验收。
例如:
git worktree add -b ai/fix-login ../app-ai-fix-login main
git worktree add -b ai/refactor-router ../app-ai-refactor-router main
git worktree add -b ai/try-new-ui ../app-ai-try-new-ui main
现在你可以把三个任务交给三个 agent,或者同一个 agent 分三轮做。每个目录都可以独立安装依赖、跑测试、看 diff、提交分支。
最后你不是面对一坨混在一起的改动,而是面对三个候选结果:
app-ai-fix-login -> 只看登录修复
app-ai-refactor-router -> 只看路由重构
app-ai-try-new-ui -> 只看新 UI 实验
这就是 AI Coding 时代 worktree 突然变重要的根本原因。
它不是让 Git 更高级,而是让 agent 的试错半径变小。
最小命令:先学这几个就够
查看当前有哪些 worktree:
git worktree list
从 main 创建一个新分支,并放到同级目录:
git worktree add -b feature/search ../app-feature-search main
这个命令做了三件事:
- 从
main创建feature/search。 - 创建
../app-feature-search目录。 - 在这个目录 checkout
feature/search。
进入这个目录后,它就是一个正常 Git 工作区:
cd ../app-feature-search
git status
git add .
git commit -m "add search"
如果要 checkout 一个已经存在、但没有被别的 worktree 占用的分支:
git worktree add ../app-release release/1.2
如果只是想临时看某个 commit,不想创建分支:
git worktree add --detach ../app-debug abc1234
删除 worktree:
git worktree remove ../app-feature-search
如果你手动删了目录,Git 里可能还残留 worktree 管理信息,可以清理:
git worktree prune
日常够用的命令其实就这些:
git worktree list
git worktree add -b <new-branch> <path> <base>
git worktree add <path> <existing-branch>
git worktree add --detach <path> <commit>
git worktree remove <path>
git worktree prune
一个完整例子:不中断当前开发,修线上 hotfix
假设你正在 feature/billing-redesign 里改了一半:
git status
看到一堆未提交文件。
这时线上登录坏了,需要马上从 main 切 hotfix。
不用 stash,也不用 checkout 回 main。直接在当前仓库里执行:
git worktree add -b hotfix/login-timeout ../app-hotfix-login main
然后:
cd ../app-hotfix-login
# 修改代码
npm test
git add .
git commit -m "fix login timeout"
git push -u origin hotfix/login-timeout
hotfix 合并后,回到原仓库:
cd ../app
git worktree remove ../app-hotfix-login
原来 feature/billing-redesign 目录里的未提交改动、打开的编辑器、临时文件都没有被动过。
这就是 worktree 最朴素、也最强的价值:不用为了切任务而破坏当前现场。
AI agent 的推荐工作流
如果把 worktree 用在 AI Coding,我更推荐一套固定流程。
1. 一个任务一个 worktree
不要让多个 agent 共用一个 worktree。共用之后,worktree 的隔离价值就没了。
推荐命名:
git worktree add -b ai/login-copy-fix ../app-ai-login-copy-fix main
git worktree add -b ai/router-refactor ../app-ai-router-refactor main
git worktree add -b ai/settings-redesign ../app-ai-settings-redesign main
分支名表达任务,目录名表达来源和用途。
2. worktree 放在项目同级,不要嵌进项目内部
推荐:
projects/
app/
app-ai-login-copy-fix/
app-ai-router-refactor/
不推荐:
app/
worktrees/
app-ai-login-copy-fix/
嵌在项目内部容易让编辑器、构建工具、搜索工具、测试脚本误扫到另一个工作区。尤其是 monorepo,嵌套 worktree 会让很多工具产生很怪的边界问题。
3. 每个 worktree 独立验证
agent 做完以后,不要只看它说“完成了”。要在那个 worktree 里看:
git status
git diff
npm test
npm run lint
或者按项目语言换成对应命令:
pytest
cargo test
go test ./...
pnpm build
worktree 的价值不是让 agent “随便改”,而是让你能按任务粒度验收。
4. 好方案进分支,坏方案直接删
如果结果好:
git push -u origin ai/router-refactor
然后开 PR,或者 cherry-pick / merge 回主线。
如果结果不好:
git worktree remove ../app-ai-router-refactor
git branch -D ai/router-refactor
这比在同一个目录里手工撤销几十个文件干净得多。
worktree 不是 sandbox
这点非常重要。
worktree 只隔离 Git 工作目录,不隔离运行时资源。
它不能自动隔离:
- 数据库;
- 端口;
- Redis、Kafka、Elasticsearch;
.env里的凭证;- 浏览器登录态;
- 系统文件访问权限;
- 后台进程;
- 网络访问。
所以多个 AI agent 同时在不同 worktree 里跑服务,仍然可能抢同一个端口:
app-ai-a -> npm run dev -> localhost:3000
app-ai-b -> npm run dev -> localhost:3000
也可能连到同一个开发数据库,互相改数据。
这就是 worktree 和 sandbox 的边界:
worktree 隔离代码现场
sandbox / container / dev env 隔离运行环境
更稳的做法是给每个 worktree 配自己的环境变量:
PORT=3001
DATABASE_URL=postgres://localhost/app_ai_login
REDIS_DB=2
如果风险更高,就配 Docker Compose project name、临时数据库、临时 bucket、临时 API token。不要以为用了 worktree,agent 就被关进安全沙箱了。
最常见的坑
1. 同一个分支不能同时被两个 worktree checkout
如果你在主目录已经 checkout 了 feature/a,再执行:
git worktree add ../app-a feature/a
Git 可能会报:
fatal: 'feature/a' is already used by worktree at ...
这是 Git 在保护你。
同一个 branch 指针如果被两个工作区同时移动,状态会非常危险。正确做法通常是新建一个分支,或者让其中一个 worktree 切到别的分支。
2. 依赖目录通常要重新安装
worktree 共享 Git 对象,不共享构建产物和依赖目录。
Node 项目常见情况是每个 worktree 都要有自己的 node_modules:
cd ../app-ai-login-copy-fix
pnpm install
pnpm、Cargo、Go、uv 这类工具有全局缓存,实际成本会低很多。但工作目录里的依赖和构建输出仍然要按项目情况处理。
3. 被 .gitignore 忽略的本地文件不会凭空出现
很多项目依赖这些本地文件:
.env
.env.local
local.sqlite
certs/dev.pem
它们通常不进 Git,所以新 worktree 里默认没有。
这不是 Git 出错,而是 Git 正常工作。你需要用项目自己的方式生成或复制本地配置。对 AI agent 来说,这一点尤其重要:如果缺 .env,agent 可能跑不起来测试,或者误以为项目坏了。
更好的做法是准备模板:
.env.example
scripts/setup-dev-env.sh
让每个 worktree 都能从可审计的模板初始化,而不是复制一份藏着真实 token 的本机文件。
4. 手动删目录后要 prune
理想情况用:
git worktree remove ../app-ai-login-copy-fix
如果你已经手动 rm -rf 了目录,Git 可能还记得那个 worktree。此时用:
git worktree prune
这会清掉已经失效的 worktree 管理记录。
5. worktree 太多会制造认知负担
worktree 解决并行,不解决管理。
如果你同时开了十几个:
git worktree list
自己也会忘记哪个目录对应哪个任务。
我的习惯是让 worktree 短命:
- hotfix 合并后删;
- AI 实验验收后删;
- PR review 结束后删;
- 长期 release 分支才保留。
一套我会实际使用的目录规范
假设主项目叫 lumen:
projects/
lumen/
lumen-ai-tokenizer-fix/
lumen-ai-ui-redesign/
lumen-hotfix-login/
lumen-review-pr-481/
lumen-release-1.4/
分支命名:
ai/tokenizer-fix
ai/ui-redesign
hotfix/login
review/pr-481
release/1.4
创建命令:
git worktree add -b ai/tokenizer-fix ../lumen-ai-tokenizer-fix main
git worktree add -b hotfix/login ../lumen-hotfix-login main
git worktree add ../lumen-release-1.4 release/1.4
清理命令:
git worktree list
git worktree remove ../lumen-ai-tokenizer-fix
git branch -D ai/tokenizer-fix
git worktree prune
这套规范的重点不是名字本身,而是让目录、分支、任务三者一一对应。以后看 git worktree list,一眼就知道哪个目录能删,哪个还在跑。
什么时候不该用 worktree
worktree 不是所有场景都必要。
如果你只是改一个小文件,几分钟内提交,普通分支就够。
如果你需要完全隔离依赖、系统包、数据库、网络和凭证,worktree 不够,需要 container、虚拟机、远程开发环境或 CI preview environment。
如果你的项目本身很大,每个 worktree 初始化依赖要几十分钟,也要控制数量。否则你只是把“切分支成本”变成了“维护多个环境的成本”。
如果团队还不熟悉 Git 基础,直接把 worktree 引入主流程也可能增加困惑。可以先从两个场景开始:hotfix 和 AI 实验。它们收益最明显,也最容易解释。
我对它的定位
git worktree 以前像一个偏高级的 Git 技巧。很多人知道 branch、stash、clone,但很少主动用 worktree。
AI Coding 把它推到了前台,因为 agent 让“同时做很多事”变成了日常需求。
人类开发者用 worktree,是为了减少上下文切换。
AI agent 用 worktree,是为了减少任务污染。
团队使用 worktree,是为了把实验、修复、review、release 变成可以并行验收的工作单元。
它不是替代 branch,也不是替代 sandbox,更不是替代代码审查。它只是把一个仓库从“单工作现场”扩展成“多工作现场”。
但这个变化很关键。
因为 AI Coding 的新问题不是“代码能不能生成”,而是“生成出来的多条路线,能不能被隔离、比较、验证和选择”。
worktree 正好提供了最小的一层工程基础设施。
自检清单
下次你想用 worktree 前,可以问自己五个问题:
- 这个任务会不会打断我当前目录里的工作现场?
- 我是不是想让 AI agent 做一个可以随时丢弃的实验?
- 我是不是需要同时看多个分支或 PR?
- 这个 worktree 有没有独立的端口、数据库和本地配置?
- 任务结束后,我准备 merge、push、cherry-pick,还是直接删除?
如果前三个问题有一个答案是“是”,worktree 很可能值得用。
如果第四个问题答不上来,就要小心:你隔离了代码,但还没有隔离运行环境。