从一个熟悉的场景说起
你正处于心流状态,代码写得行云流水,feature 分支上的新功能即将成型。这时候,Slack 弹出一条消息——线上出了 P0 故障,需要立刻修复。又或者,产品经理冲过来说"有个紧急需求,老板今天要看"。
怎么办?git stash 把当前改动藏起来,切到 main 拉个分支修 bug,修完再切回来 git stash pop?这套操作你可能已经做过无数次了。但 stash 栈一旦积攒多了,哪个是哪个根本分不清。更别提 stash 之前还得确认哪些文件该暂存、哪些不该——稍有不慎,改动就丢了。
再看看 AI 编程的场景。你想让两个任务同时推进:一个做功能开发,一个做代码重构。但两个任务如果在同一个工作目录里交替进行,文件改动互相覆盖,结果只会一团乱麻。什么,复制一份代码仓库?几个 G 的 .git 目录再来一份,硬盘表示抗议。
其实,Git 早就替你想好了解决方案:worktree。
Git Worktree:一个仓库,多个工作目录
git worktree 允许你在同一个仓库下同时检出多个工作目录,每个目录对应不同的分支。无需 stash,无需 commit 半成品代码,就能并行处理多个任务。
核心概念
- 每个 git 仓库有一个主工作树(main worktree),就是你
clone时创建的那个目录 - 通过
git worktree add可以创建链接工作树(linked worktree),它们共享同一个.git仓库数据 - 每个工作树必须检出不同的分支——同一分支不能同时被两个工作树使用
一句话概括:多个目录,一份仓库数据,各干各的活。
下面这张架构图展示了 Git Worktree 的运行原理——一个共享的 .git 仓库,挂载多个独立的工作树,每个工作树可以从不同的基准分支创建:
flowchart TB
subgraph repo["共享 .git 仓库"]
objects[("对象库\ncommits / trees / blobs")]
refs["引用\nbranches / tags"]
meta["config / hooks\nstash / reflog"]
end
repo <-->|"读写"| main_wt
repo <-->|"读写"| hotfix_wt
repo <-->|"读写"| feature_wt
subgraph main_wt["主工作树 ~/project/"]
m1["HEAD -> main"]
m2["独立 INDEX"]
m3["工作文件"]
end
subgraph hotfix_wt["链接工作树 ../hotfix/"]
h1["HEAD -> hotfix/login-crash"]
h2["独立 INDEX"]
h3["工作文件"]
end
subgraph feature_wt["链接工作树 ../feature/"]
f1["HEAD -> feature/new-auth"]
f2["独立 INDEX"]
f3["工作文件"]
end
base_main(["main 分支"]) -.->|"基准分支"| hotfix_wt
base_dev(["origin/dev 分支"]) -.->|"基准分支"| feature_wt
style repo fill:#e8f4fd,stroke:#2196F3,color:#000
style main_wt fill:#e8f5e9,stroke:#4CAF50,color:#000
style hotfix_wt fill:#fff3e0,stroke:#FF9800,color:#000
style feature_wt fill:#fce4ec,stroke:#E91E63,color:#000
style base_main fill:#fff,stroke:#999,stroke-dasharray: 5 5,color:#000
style base_dev fill:#fff,stroke:#999,stroke-dasharray: 5 5,color:#000
常用命令
1. 创建工作树
# 基于现有分支创建工作树
git worktree add ../hotfix-dir hotfix/critical-bug
# 创建新分支并检出到工作树
git worktree add -b feature/new-login ../new-login-dir
# 基于远程分支创建
git worktree add ../review-dir origin/feature/review
2. 查看所有工作树
git worktree list
输出示例:
/home/user/my-project abc1234 [main]
/home/user/hotfix-dir def5678 [hotfix/critical-bug]
/home/user/new-login-dir 789abcd [feature/new-login]
3. 删除工作树
# 推荐:直接 remove【推荐】
git worktree remove ../hotfix-dir
# 或者手动删除目录后清理记录
rm -rf ../hotfix-dir
git worktree prune
典型使用场景
场景一:紧急修复 Bug,不打断当前开发
你正在 feature/dashboard 上写代码,线上突然炸了:
# 不需要 stash,直接创建新工作树
git worktree add -b hotfix/login-crash ../hotfix main
cd ../hotfix
# 修复 bug、提交、推送
vim src/login.js
git commit -am "fix: login crash on null user"
git push origin hotfix/login-crash
# 修完后回到原工作目录继续开发
cd ../my-project
git worktree remove ../hotfix
全程没有碰过原来的工作目录,feature/dashboard 上写到一半的代码纹丝不动。
场景二:同时运行两个分支做对比
# 主目录运行 main 分支的服务
cd ~/project && npm run dev # 端口 3000
# 另一个工作树运行 feature 分支
git worktree add ../project-feature feature/new-api
cd ../project-feature && PORT=3001 npm run dev # 端口 3001
# 浏览器同时打开两个端口,直接对比效果
场景三:Code Review 时查看 PR 代码
# 拉取 PR 分支到独立工作树
git fetch origin pull/42/head:pr-42
git worktree add ../pr-42-review pr-42
cd ../pr-42-review
# 阅读代码、运行测试,不影响主工作区
npm test
# 审完清理
cd ../my-project
git worktree remove ../pr-42-review
Worktree vs 其他方案
| 方案 | 切换成本 | 磁盘占用 | 并行工作 |
|---|---|---|---|
git stash + checkout | 高(需保存/恢复状态) | 低 | 不支持 |
git clone(多份副本) | 低 | 高(完整仓库副本) | 支持 |
git worktree | 低 | 低(共享 .git) | 支持 |
注意事项
- 同一分支不能同时被两个工作树检出
- 不要直接
rm -rf工作树目录了事,应使用git worktree remove或删后执行git worktree prune - 工作树之间共享 stash、reflog 等仓库级数据
- 子模块(submodule)在工作树中需要额外初始化
Claude Code 内置 Worktree 支持
Claude Code 的负责人 Boris Cherny 在 X 上宣布:Claude Code CLI 现在内置了 Git Worktree 支持,各智能体可以并行运行,互不干扰。
这意味着 AI 辅助编程进入了"多线程"时代——你可以同时启动多个 Claude 会话,每个会话在独立的 worktree 中工作,彼此完全隔离。
下图展示了 Claude Code Worktree 的整体架构——开发者通过 CLI 启动多个 Agent 会话,每个会话在
.claude/worktrees/ 下的独立工作树中运行,共享同一个 .git 仓库,同时支持通过 Hooks 扩展到非 Git 版本控制系统:
flowchart TB
user(["开发者"])
user -->|"终端1: claude -w feature-auth"| agent1["Claude Agent\n会话 1"]
user -->|"终端2: claude -w bugfix-123"| agent2["Claude Agent\n会话 2"]
user -->|"终端3: claude -w refactor"| agent3["Claude Agent\n会话 3"]
agent1 -->|"读写文件 / 执行命令"| wt1
agent2 -->|"读写文件 / 执行命令"| wt2
agent3 -->|"读写文件 / 执行命令"| wt3
subgraph claude_dir[".claude/worktrees/"]
wt1["feature-auth/\n分支: feature-auth\n基于 HEAD"]
wt2["bugfix-123/\n分支: bugfix-123\n基于 HEAD"]
wt3["refactor/\n分支: refactor\n基于 HEAD"]
end
wt1 & wt2 & wt3 -->|"共享"| git[(".git 仓库")]
subgraph hooks_ext["Hooks 扩展(非 Git 项目)"]
hooks["WorktreeCreate\nWorktreeRemove"]
hooks -->|"适配"| hg["Mercurial"]
hooks -->|"适配"| p4["Perforce"]
hooks -->|"适配"| svn["SVN"]
end
git ~~~ hooks_ext
style user fill:#f5f5f5,stroke:#333,color:#000
style claude_dir fill:#e8f4fd,stroke:#2196F3,color:#000
style git fill:#e8f5e9,stroke:#4CAF50,color:#000
style hooks_ext fill:#fff3e0,stroke:#FF9800,color:#000
style agent1 fill:#ede7f6,stroke:#673AB7,color:#000
style agent2 fill:#ede7f6,stroke:#673AB7,color:#000
style agent3 fill:#ede7f6,stroke:#673AB7,color:#000
Claude Code Worktree 用法
启动方式
# 指定名称创建 worktree
claude --worktree feature-auth
claude -w bugfix-123
# 自动生成名称
claude -w
执行后,Claude Code 会:
- 在
.claude/worktrees/<名称>/下创建独立的工作目录 - 基于当前 HEAD 自动创建一个同名的 git 分支
- 在该隔离环境中启动 Claude 会话
典型工作流
# 终端 1:开发新功能
claude --worktree feature-new-auth
# 终端 2:修复 bug(同一仓库,独立环境)
claude --worktree bugfix-dashboard
# 终端 3:重构代码
claude --worktree refactor-utils
三个会话各自独立运行,互不影响。
在会话内创建 worktree
在 Claude Code 交互过程中,也可以随时创建 worktree 来隔离工作:
> 请在 worktree 中工作
Claude 会自动调用内置的 worktree 功能,创建隔离环境并切换过去。
通过 Hooks 扩展到非 Git 项目
Claude Code 的 worktree 功能并不局限于 Git 仓库。通过配置 WorktreeCreate 和 WorktreeRemove hooks,可以将这套隔离机制扩展到 Mercurial、Perforce、SVN 等版本控制系统。对于使用非 Git 版本控制的团队,这提供了一种统一的并行开发方式。
清理
使用完毕后,退出会话时 Claude Code 会提示你是否保留或清理 worktree。建议在 .gitignore 中添加:
.claude/worktrees/
Git Worktree vs Claude Code Worktree
两种 worktree 用法都能实现并行开发,但在细节上有明显差异:
| 对比维度 | Git Worktree | Claude Code Worktree |
|---|---|---|
| 依赖 | 仅依赖 Git | 依赖 Claude Code CLI |
| 基准分支 | 可从任意分支/commit 创建 | 只能从当前 HEAD 创建 |
| 工作树位置 | 自由指定路径 | 固定在 .claude/worktrees/ 下 |
| 分支命名 | 完全自定义 | 与 worktree 名称绑定 |
| 适用场景 | 通用 Git 工作流 | Claude Code AI 编程场景 |
| 非 Git 支持 | 不支持 | 通过 Hooks 可扩展 |
| 会话管理 | 无 | 支持 /resume 切换会话 |
推荐优先使用 git worktree。 理由很简单:
第一,它不依赖任何第三方工具。不管你用 VS Code、Vim、JetBrains 还是 Claude Code,git worktree 都能正常工作。工具链的依赖越少,工作流就越稳定。
第二,git worktree 支持从任意分支或 commit 创建工作树,而 Claude Code 只能基于当前 HEAD。当你需要从 main 分支拉一个 hotfix,但当前在 feature/xyz 上时,git worktree add -b hotfix ../hotfix main 一条命令搞定,Claude Code 的 worktree 做不到这一点。
当然,如果你的工作流完全围绕 Claude Code 展开,或者需要用到非 Git 版本控制系统的 Hooks 扩展能力,Claude Code 的 worktree 仍然是一个不错的选择。
Worktree 存在的问题
Worktree 并非银弹,使用中有两个绕不开的问题。
依赖和缓存需要重新加载
每个 worktree 是一个独立的工作目录,但 node_modules、构建缓存、IDE 索引等并不会共享。新建一个 worktree 后,你通常需要重新 npm install(或 pnpm install),等待依赖安装完成,IDE 也需要重新索引。对于大型项目,这个开销并不小。
一些缓解办法:使用 pnpm 的全局 store 可以减少重复下载;把构建缓存放到仓库外的共享目录;或者在创建 worktree 后用脚本自动初始化环境。但无论如何,这笔"启动成本"是客观存在的。
代码冲突被推迟到 PR 阶段
多个 worktree 并行开发时,每个人在自己的分支上写得很顺畅,冲突感知为零。但这不代表冲突不存在——它只是被推迟了。等到多个分支的 PR 同时合入主干时,冲突会集中爆发。
特别是当多个 worktree 修改了同一个文件的相邻区域时,合并冲突往往比预期的更复杂。建议在并行开发时保持对主干的频繁 rebase,尽早暴露冲突,而不是等到最后才面对一堆 conflict markers。
结语
无论是传统的多分支开发,还是 AI 驱动的多智能体协作,并行开发正在成为常态。git worktree 作为 Git 原生提供的轻量级方案,用最小的磁盘开销和最低的切换成本,解决了"一个仓库、多条战线"的问题。
掌握 worktree,是每个现代开发者的必备技能。下次再遇到"正在写代码突然要切分支"的场景,不要再 git stash 了——开个 worktree,两边的活一起干。