Git Worktree 与cursor workTree完全指南

7 阅读15分钟

1. 引言:那个让你抓狂的“突发需求”

想象一下这个场景: 你正在 feature-awesome 分支上热火朝天地写着几百行核心代码,正处于“心流”状态。突然,老板冲进办公室:“生产环境出 Bug 了,赶紧切到 master 修复一下!”

此时的你陷入了纠结:

  • 方案 A:git stash。把改了一半的代码藏起来。等你修完 Bug 回来 stash pop 时,往往会因为忘记了当时的环境或者遇到冲突而一脸懵。
  • 方案 B:直接 git checkout。报错!Git 提醒你本地修改会被覆盖,切不过去。
  • 方案 C:暴力 git clone。在另一个文件夹再克隆一份项目。不仅浪费硬盘空间,还得重新装依赖、配置环境变量,半小时过去了。

有没有一种办法,能让我像切浏览器标签页一样,同时打开多个分支工作,互不干扰?

这就是我们要聊的主角:Git Worktree


2. 什么是 Git Worktree?

Git Worktree 是 Git 的一个高级功能,允许你基于同一个本地 Git 仓库,在不同的文件夹里同时检出(checkout)多个不同的分支

传统方式的痛点

通常你在一个文件夹里只能处于一个分支。如果你想同时看两个分支的代码,你要么频繁地 git checkout 切来切去,要么把整个仓库重新 git clone 一份(浪费硬盘空间且不同步)。

Worktree 的优势

  1. 秒级创建:不需要重新下载或复制(.git 目录里的历史数据是共享的)
  2. 完全隔离:每个 worktree 都有自己独立的运行环境、node_modules 等,互不干扰
  3. 状态同步:因为底层是同一个仓库,在一个工作区提交的代码,在另一个工作区切换分支立刻就能看到

3. 通俗比喻

比喻一:共享云盘

把 Git 仓库想象成一个带密码的共享云盘

  • 传统的 Git:你本地只有一个文件夹(本地副本)。你想看另一个分支的代码,就必须把当前的文件夹内容替换掉。
  • Git Worktree:你在本地同时打开了两个独立的文件夹窗口。这两个窗口都能看到云盘里的所有内容(所有分支),但你可以在窗口 A 里切换到分支 A,在窗口 B 里切换到分支 B。它们操作的是同一个云盘,提交的文件会自动同步到云端

比喻二:书本的全息投影

假设你的项目是一本厚厚的书,项目的 .git 隐藏文件夹就是这本书的**“核心记忆库”**。

  • 传统的 Git:你桌子上只有一个阅读架(一个目录)。想看 A 分支的代码就摆 A,想看 B 分支就必须把 A 收起来换成 B。无法同时摊开对比。
  • 传统的笨办法(Copy 一份整个项目):相当于去书店又买了一本一模一样的书。缺点是极度浪费硬盘空间,且两本书是断开连接的。
  • Git Worktree(魔法分身):召唤出这本书的**“全息投影”。你可以同时在两个文件夹里看不同分支的内容,但它们共享同一个“核心记忆库”**。

比喻三:乐高工作台

想象你正在拼一套复杂的“星球大战”乐高(这是你的主项目)。

  • 传统的 Git 像是一个只有一个桌面的工作台。你想拼“死星”,就得把还没拼好的“千年隼”拆掉或收进盒子里,腾出地方。
  • Git Worktree 则是给你瞬间变出第二个、第三个独立的工作台。这些工作台共享同一个零件仓库(.git 目录),但桌面是独立的。你可以在台子 A 修 Bug,在台子 B 写新功能,抬头就能看见彼此,转身就能切换。

4. 使用场景

Git Worktree 适用于以下场景:

场景一:紧急 Bug 修复 + 功能开发并行

当你正在开发新功能时,突然需要去修复生产环境的 Bug。使用 Worktree,你可以:

  • 在主目录继续开发新功能(不中断工作流)
  • 创建一个新的 Worktree 去修复 Bug
  • Bug 修复完成后,合并代码,回到主目录继续写代码

场景二:多任务并行(双 AI 竞技)

你想让两个 AI 各自实现同一个功能,然后比较效果。

  • 为 AI-A 创建一个 Worktree + 新分支
  • 为 AI-B 创建一个 Worktree + 新分支
  • 两个 AI 同时在各自的目录里写代码
  • 完成后对比效果,选择更好的合并

场景三:代码审查

在提交 PR 之前,想在本地先跑一下另一个分支的代码看看效果?

  • 创建一个 Worktree 检出那个分支
  • 审查完毕后删除 Worktree

场景四:并行测试

需要在同一个项目上跑不同的测试套件,但测试会修改代码?

  • 创建多个 Worktree,每个跑不同的测试
  • 互不干扰

5. 底层原理:.git 文件夹的变化

核心逻辑

在 Git 的世界里,一个仓库通常由两部分组成:

  1. .git 文件夹(仓库的灵魂:存储历史、版本信息)
  2. 工作区(仓库的肉体:你实际看到的代码文件)

默认情况下,一个灵魂只配一个肉体。但 Git Worktree 允许一个 .git 文件夹同时管理多个工作区

主目录(Main Worktree)

假设你的主项目在 D:\projectA,里面有一个真正的 .git 文件夹,包含了项目所有的历史提交记录、代码对象库等。

使用 worktree 后,Git 会在 D:\projectA\.git\ 里面悄悄新建一个 worktrees 子文件夹:

D:\projectA\
├── .git/                 <-- 真正的文件夹
│   ├── objects/          <-- 存放所有历史代码(体积最大,两边共享)
│   ├── config            <-- 共享的配置文件
│   └── worktrees/        <-- 新增的秘密基地
│       └── projectB/     <-- 记录 projectB 状态的子文件夹
│           ├── HEAD      <-- 记录 projectB 当前停留在哪个分支
│           └── index     <-- 记录 projectB 的暂存区
└── package.json ...

新工作区(Linked Worktree)

新创建的 worktree 目录里,.git 不是一个文件夹,而是一个普通的文本文件,里面只有一行字:

gitdir: D:/projectA/.git/worktrees/projectB

这就是为什么新目录几乎不占空间 —— 它只是一个“指针”,指向主项目的数据库。


6. 核心概念:分支关系

⚠️ 重要提醒:工作区应建在主项目的同级目录

不要把 worktree 目录建在主项目文件夹里面!

正确做法:使用 ../ 路径,建在主项目的上一级目录(即同级目录)。

# 假设主项目在 D:\projects\my-app
# 正确:建在 D:\projects\my-app-ai-a
git worktree add ../my-project-ai-a -b ai-a-task

# 错误:会污染主项目目录!
# git worktree add ./my-app-ai-a -b ai-a-task  ❌

这样创建后,文件系统是这样的:

D:\projects\
├── my-app/           <-- 你的主项目(干净)
├── my-app-ai-a/      <-- AI-A 的工作区(独立)
└── my-app-ai-b/      <-- AI-B 的工作区(独立)

合并代码后,用 git worktree remove 清理,主项目目录依然是干净的


分支是全局共享的

多个 worktree 之间,分支列表是完全共享的。

  • 如果你在 AI-A 的 worktree 目录里新建了一个分支 git branch test-ai
  • 你马上切回到主目录,敲 git branch,会立刻看到 test-ai 这个分支
  • 它们共享同一个大本营

代码提交是瞬间同步的

因为底层数据库是同一个:

  • AI-A 在它的目录里,在 ai-a-task 分支上做了一个 Commit
  • 这个 Commit 瞬间被永久写入主目录的 .git 数据库里
  • 哪怕你把 AI-A 的实体文件夹物理删除了,代码也不会丢

Worktree 分支与原项目分支的关系

它们根本就是同一个东西。没有任何区别,完全共享。

⚠️ 关键点(必读):在 Worktree 目录里的所有操作(提交、推送),都是直接作用于对应的分支。

  • git worktree add ../my-project-hotfix hotfix 创建的工作区,检出的就是 hotfix 分支
  • 在这个目录里 git commit,代码直接提交到本地的 hotfix 分支
  • 在这个目录里 git push,代码直接推送到远端的 hotfix 分支
  • 不存在"属于哪个项目"的区别,这个 Worktree 就是分支的"另一个窗口"

不要把 worktree 想象成"主仓库的克隆/子仓库"。你可以把整个 Git 仓库想象成一个**"共享保险箱(.git 目录)"**,里面存放着所有的代码和所有的分支。

  • 在 Worktree B 里的提交 = 直接修改主项目的分支 A
  • 不存在"主项目的 A 分支"和"B 项目的 A 分支"这种区分
  • 在 worktree 目录 B 中对分支 A 做提交:
    • Commit 的数据写入主项目的 .git/objects 数据库
    • 分支 A 的指针向前移动
    • 回到主项目执行 git log A 能立刻看到这个提交

最重要规则:互斥检出

同一个分支,同一时刻,只能被一个目录使用。

  • 假设主目录当前停留在 main 分支
  • 如果此时你敲 git worktree add ../new-dir mainGit 会直接报错拒绝
  • Git 的理由是:主目录正在使用 main 分支,新目录必须用别的分支,防止同时改文件导致混乱

7. 双 AI 竞技实战流程

步骤一:创建 Worktree

在主项目目录下执行:

# 为 AI-A 创建一个新分支 ai-a-task,并放到 ../my-project-ai-a 文件夹
git worktree add ../my-project-ai-a -b ai-a-task

# 为 AI-B 创建一个新分支 ai-b-task,并放到 ../my-project-ai-b 文件夹
git worktree add ../my-project-ai-b -b ai-b-task

注意:路径 ../ 表示建在主项目的上一级目录,避免污染主项目。

步骤二:让 AI 开始干活

  • 让 AI-A 在 my-project-ai-a 文件夹里写代码
  • 让 AI-B 在 my-project-ai-b 文件夹里写代码
  • 它们可以同时运行自己的开发服务器、独立安装依赖,完全不会冲突

步骤三:比较效果

  • 分别在两个目录下运行项目,直观对比 UI 或功能效果
  • 或者使用 git diff ai-a-task..ai-b-task 比对代码差异

步骤四:合并代码(假设 AI-A 写得更好)

  1. 回到主项目目录
  2. 合并 AI-A 的分支
cd ../my-project
git checkout dev          # 确保你在开发分支
git merge ai-a-task       # 把 AI-A 的劳动成果合并过来

步骤五:清理 Worktree

代码已经合并了,临时目录使命结束:

# 删除 worktree 目录(Git 会自动从硬盘删除这两个文件夹)
git worktree remove ../my-project-ai-a
git worktree remove ../my-project-ai-b

# 可选:删除临时分支
git branch -d ai-a-task
git branch -d ai-b-task

8. 命令详解

创建 Worktree

# 方式一:创建一个全新的分支(推荐用于新任务)
git worktree add <路径> -b <新分支名>

# 方式二:基于已存在的分支(本地或远端)
git worktree add <路径> <分支名>

示例 1:本地没有该分支,Git 会自动从远端拉取

git worktree add ../my-project-hotfix hotfix
  • 如果本地没有 hotfix 分支,Git 会自动去远端找
  • 自动在本地创建 hotfix 分支,与远端关联
  • 然后检出到新目录

示例 2:创建全新的分支

git worktree add ../my-project-ai-a -b ai-a-task
  • -b 表示创建并切换到一个全新的分支
  • 适合让 AI 开始干一个全新的任务

查看 Worktree 列表

git worktree list

移除 Worktree

# 安全删除(确保没有未提交的代码)
git worktree remove <路径>

# 强制删除(如果有未提交的代码)
git worktree remove <路径> --force

清理无效 Worktree

如果手动删除了 worktree 文件夹,但没告诉 Git:

git worktree prune

9. 常见问题

Q: Worktree 里的提交属于主项目的分支吗?

是的,完全属于。

⚠️ 再次强调:在 Worktree 目录里的提交和推送,都是直接作用于对应的分支。

例如:你执行了 git worktree add ../my-project-hotfix hotfix,然后在 my-project-hotfix 目录里:

cd ../my-project-hotfix
echo "fix bug" > bug.txt
git add .
git commit -m "修复了一个Bug"
git push origin hotfix  # 推送到远端的 hotfix 分支
  • 这个 Commit 直接写入 hotfix 分支的历史
  • 回到主项目执行 git log hotfix 能立刻看到这个提交
  • 推送到远端时,推送的是 hotfix 分支,不是新建了一个分支
  • 在 Worktree 里提交 = 直接修改分支,推送 = 直接推送到该分支的远端

在 Git Worktree 的世界里,根本不存在"主项目的 A 分支"和"B 项目的 A 分支"这种区分。整个仓库里,自始至终只有一个 A 分支。

在 worktree 目录 B 中对分支 A 做提交:

  • Commit 的数据写入主项目的 .git/objects 数据库
  • 分支 A 的指针向前移动
  • 回到主项目执行 git log A 能立刻看到这个提交

Q: 本地没有某个分支,但远端有,怎么创建 Worktree?

直接写分支名即可,不需要写 origin/xxx

git worktree add ../new-dir hotfix

Git 会自动检测本地没有这个分支,然后去远端拉取并创建本地分支。

注意:不要写成 git worktree add ../new-dir origin/hotfix,这会导致你在新目录里处于“游离状态(Detached HEAD)”,无法正常提交。

Q: 两个 worktree 可以同时使用同一个分支吗?

不能。Git 会报错:

fatal: 'main' is already checked out at '.../主项目目录'

这是为了防止两个目录同时修改同一个分支导致冲突。

Q: Worktree 目录可以建在主项目里面吗?

不推荐。虽然技术上可以,但会污染主项目的目录结构。

推荐做法:始终使用 ../ 路径,建在主项目的同级目录。这样:

  • 主项目目录保持干净
  • 合并代码后,用 git worktree remove 清理,物理文件夹会自动消失
  • 不会把 worktree 的文件误提交到主项目

10. 完整工作流示例

# 1. 在主项目目录(假设在 D:\projects\my-app),创建两个 worktree
git worktree add ../my-app-ai-a -b ai-a-task
git worktree add ../my-app-ai-b -b ai-b-task

# 2. AI-A 和 AI-B 分别在各自的目录里写代码、提交
# (假设 AI-A 完成了)

# 3. 回到主项目,合并 AI-A 的代码
cd ../my-app
git checkout dev
git merge ai-a-task

# 4. 清理:删除 worktree 和临时分支
git worktree remove ../my-app-ai-a
git worktree remove ../my-app-ai-b
git branch -d ai-a-task
git branch -d ai-b-task

# 5. 完成后,主目录依然是干净的,只有 my-app 一个文件夹

11. Cursor Worktree vs Git Worktree

本节介绍 Cursor 编辑器的 Worktree 功能,它是 Git 原生 Worktree 的“AI 增强版”。

什么是 Cursor Worktree?

Cursor 的 Worktree 是建立在 Git 原生 Worktree 之上的“AI 增强版工作区”。

Cursor 利用 Git Worktree 的底层能力,但在此基础上添加了自动化管理、智能对比和一键合并等功能,专门为"让多个 AI 代理同时干活"这个场景优化。

核心区别

特性Git 原生 WorktreeCursor Worktree
创建方式手动敲命令 git worktree addAI 自动创建,你只需要点按钮
分支管理手动创建、切换、删除自动为每个 Agent 创建独立分支
代码合并手动 git merge点击"Apply"按钮一键合并
多模型对比需自己搭建内置"Best-of-N"功能,多个模型同时跑,结果对比展示
初始化无自带机制支持 worktrees.json 自动安装依赖、复制环境变量
清理机制手动 git worktree remove自动清理(最多20个,按访问时间删除)

它们之间的联系

Cursor Worktree 就是 Git 原生 Worktree 的“高级封装”。

当你用 Cursor 创建一个并行代理时:

  1. Cursor 会在后台调用 git worktree add 创建新目录
  2. 分支是自动创建的(比如 feat-1-98Zlw
  3. 文件路径类似 /Users/<you>/.cursor/worktrees/<repo>/98Zlw

从终端运行 git worktree list,你会看到:

/.../<repo>                                  15ae12e   [main]
/Users/<you>/.cursor/worktrees/<repo>/98Zlw  15ae12e   [feat-1-98Zlw]
/Users/<you>/.cursor/worktrees/<repo>/a4Xiu  15ae12e   [feat-2-a4Xiu]

本质上就是 Git Worktree,只是 Cursor 帮你做了:

  • 自动创建
  • 自动清理
  • 自动复制环境变量
  • 可视化的合并界面

Cursor Worktree 的独特优势

1. Best-of-N(多模型竞技)

这是 Cursor 独有的功能:

  • 同一个提示词,让多个模型同时跑
  • 生成多张卡片,分别展示每个模型的改动
  • 你可以对比挑选最好的结果,一键 Apply

2. 初始化脚本(开箱即用)

通过 .cursor/worktrees.json 配置,新 Worktree 创建时自动:

  • 安装依赖(npm ci / pnpm install
  • 复制环境变量文件(.env
  • 运行数据库迁移

3. 自动清理防占盘

  • 最多 20 个 Worktree
  • 自动删除最早访问的
  • 不需要手动管理

总结:一句话理解

Cursor Worktree 就是“Git Worktree 的懒人版”,它把创建分支、装依赖、合并代码这些脏活累活都替你干了,你只需要点按钮让 AI 干活,然后挑最好的结果合并进来。


12. 总结


11. 总结

  • Worktree 不是克隆仓库,而是给同一个仓库开了多个“操作窗口”
  • 分支是共享的,不是独立的副本
  • 代码提交在哪里提交,就属于哪个分支,不存在“属于哪个项目”的区别
  • 用完即焚,通过 git worktree remove 清理
  • 工作区应建在主项目的同级目录,避免污染主项目
  • 它比 stash 更安全,比 clone 更轻量(共享 .git 目录,极省空间)