Git Worktree (工作树 / 多工作区)

一句话:让同一个 Git 仓库的多个分支同时 checkout 到多个独立目录,这些目录共享同一个 .git 对象库。

1. 定义

git worktree 让你在不切换当前分支、不 stash 当前改动的情况下,把仓库的另一条分支「展开」到磁盘上的另一个文件夹里。所有 worktree 共用同一个 .git(对象数据库 / refs),只是各自有独立的工作区与 HEAD。

类比:同一栋楼(仓库)里分出好几间独立办公室(worktree),每间都能同时开工,但共用一个档案室(对象数据库)。

2. 核心概念 / 解决什么问题

概念说明
共享 .git所有 worktree 指向同一个仓库存储,不重复占用对象库磁盘
独立工作区每个 worktree 有自己独立的文件树与 HEAD(所在分支)
并行分支不用 stash / checkout 来回切,就能同时在不同分支上干活
多 agent 隔离每个 agent 一个 worktree,编辑互不踩脚、不抢同一工作区

解决的痛点:传统「想并行做两件事」要么 clone 两份仓库(占磁盘、需同步),要么反复 stash/切分支(打断状态)。worktree 两者都不需要。

3. 工作原理 / 在系统中的位置

my-repo/                      <- 主工作区 (branch: main)
├── .git/                     <- 唯一的对象库 / refs(所有 worktree 共享)
├── src/ ...
└── .worktrees/
    ├── agent-1/              <- worktree A (branch: feat/a)
    │   ├── src/ ...          <- 独立文件树
    │   └── (指向 .git,无自己的 .git 目录)
    └── agent-2/              <- worktree B (branch: feat/b)
        └── src/ ...

每个 worktree 下没有自己的 .git/ 目录,而是一个指向主仓库 .git 的链接;git worktree list 的元数据存在 .git/worktrees/ 里。

4. 基本用法 / 常用命令

# 1. 新建一个 worktree,并切到(或新建)某分支
git worktree add ../my-repo-featA feat/A        # 在 ../my-repo-featA 展开 feat/A 分支
git worktree add .worktrees/agent-1 -b feat/b   # 新建 feat/b 分支并展开到 .worktrees/agent-1
 
# 2. 列出当前所有 worktree
git worktree list
 
# 3. 用完删除某个 worktree(先确保里面的改动已提交/丢弃)
git worktree remove .worktrees/agent-1
 
# 4. 清理已被手动删除目录后遗留的无效记录
git worktree prune

多 agent 场景:leader 给每个 subagent git worktree add .worktrees/<name> -b <branch>,agent 在各自目录里编辑,结束后 leader 合并分支再 remove

5. 对比辨析表

维度git worktreegit clone(多份)切分支 git checkout
磁盘占用共享 .git,省每份都存完整 .git,费共享,最省
能否并行✅ 多分支同时开工✅ 但需手动同步❌ 一次只能在一个分支
改动隔离✅ 独立工作区✅ 完全隔离❌ 需 stash 才能切换
适用并行任务 / 多 agent跨机协作单线顺序工作

6. 典型工作流

  • 多 agent 协作:leader 为每个队友开一个 worktree(各自独立分支)→ 并行开发 → leader 合并 → git worktree remove 清理。
  • 自己并行:主分支查 bug 的同时,在另一个 worktree 写新功能,两边状态互不干扰。
  • 临时评审:git worktree add /tmp/review -b pr-123 拉下别人的 PR 分支本地跑一遍,看完直接删。

7. 常见误区

  • worktree 是新 clone → 错。它共享同一个 .git 对象库,只是多了一个独立工作目录;删除 worktree 不会删除分支,也不会动主仓库。
  • 同一分支能开两个 worktree → 不行。一个分支同一时刻只能隶属于一个 worktree(否则两边互相覆盖)。要并行请用不同分支。
  • 在 worktree 里还能随便切分支 → 可以,但切到「已在别的 worktree 打开的分支」会被 Git 拒绝,这是保护机制。

8. 延伸阅读 / 关联概念

  • git-graph — 提交历史的有向无环图可视化(看分支怎么分叉/合流)
  • git-branch基础 — 分支与 HEAD 的关系
  • 官方文档:git help worktree