一个仓库(.git)可以挂多个工作目录:每个目录各自检出不同分支,共享同一份对象库与历史,互不影响对方的未提交改动。
传统用法里,一个 clone 同一时间只能 checkout 一个分支。要并行改两个分支,通常只能再 clone 一份,代价是:
- 重复下载、重复占用磁盘上的对象
- 两个 clone 的配置、hooks、reflog 容易漂移
git worktree 解决的是:同一仓库,多份检出。适合:
- 主线继续开发,另开目录修 hotfix
- 一边跑长构建/测试,一边在别的分支改代码
- AI Agent / IDE 在隔离目录里并行实验,不弄脏主工作区
repository(一份 .git)
├── main worktree ← clone / init 时的那个目录
│ ├── HEAD → branch A
│ ├── index
│ └── 工作区文件
└── linked worktrees ← git worktree add 加出来的
├── /path/to/wt-b → branch B
└── /path/to/wt-c → branch C(或 detached HEAD)
| 概念 | 含义 |
|---|---|
| Main worktree | git clone / git init 得到的主工作树 |
| Linked worktree | 用 git worktree add 挂上的额外工作树 |
| 共享 | commits、blobs、refs、config(仓库级) |
| 不共享 | 每个 worktree 自己的 HEAD、index、未跟踪文件、部分 per-worktree 配置 |
约束:同一个分支不能同时被两个 worktree 检出(避免两个目录改同一分支、提交互相踩踏)。需要并行时,给新 worktree 建新分支,或用 --detach。
主仓库里会多出管理信息,大致在:
.git/worktrees/<id>/
├── HEAD # 该 worktree 当前指向
├── gitdir # 指向该工作目录里的 .git 文件
├── locked # 若被 lock
└── ...
Linked worktree 目录里通常不是完整 .git 文件夹,而是一个文件,内容类似:
gitdir: /path/to/main-repo/.git/worktrees/<id>
所以删目录时若不走 git worktree remove,主仓库里可能留下过期的管理条目,需要 prune 清理。
git worktree list
git worktree list -v# 在 path 创建新分支(分支名默认取 path 最后一段)并检出
git worktree add ../hotfix
# 检出已有分支到新目录
git worktree add ../feature-foo feature-foo
# 显式建新分支再检出
git worktree add -b experiment ../experiment main
# 临时实验:detached HEAD,不绑分支
git worktree add --detach ../scratchgit worktree move <worktree> <new-path>
git worktree remove <worktree>
git worktree remove -f <worktree> # 有未提交改动时强制
# 工作目录已被手动删掉时,清掉残留元数据
git worktree prune工作树在外置盘或不常挂载的路径上时,可 lock,避免被自动 prune:
git worktree lock ../portable-wt --reason "on USB drive"
git worktree unlock ../portable-wt# 当前在 main 上开发
cd ~/proj
# 紧急修复:另开目录,从 main 拉 hotfix 分支
git worktree add -b hotfix/login ../proj-hotfix main
cd ../proj-hotfix
# ... 修、测、提交、推送 ...
git push -u origin hotfix/login
# 用完后回到主目录清理
cd ~/proj
git worktree remove ../proj-hotfix主目录里的未提交改动不受影响;hotfix 目录有自己的 index 与工作区。
| 再 clone | worktree | |
|---|---|---|
| 对象库 | 各一份(或靠引用复制仍偏重) | 共享一份 |
| 分支可见性 | 需分别 fetch | 同一仓库,立刻可见 |
| 并行检出不同分支 | 可以 | 可以 |
| 清理 | 删整个目录 | remove + 必要时 prune |
| 适用 | 完全隔离的机器/权限边界 | 本机并行开发、临时实验 |
- 分支独占:
branch X已在某个 worktree,就不能再add检出到另一个;用-b新分支或--detach。 - 删目录要用命令:直接
rm -rf工作目录后,记得git worktree prune。 - 子模块 / 依赖:每个 worktree 是独立工作区;
node_modules等通常各自安装,不共享。 - bare 仓库:可以只有 linked worktrees、没有「带工作区的 main」;常见于集中管理多检出的布局。
- Cursor / Agent:隔离实验目录时,worktree 比改同一工作区再 stash 更干净——主目录继续用,实验目录随时丢弃。
Worktree = 共享历史的额外 checkout。
改的是「当前这个目录的分支与文件」;提交仍进同一个仓库。用完remove,别只删文件夹。
man git-worktree/git worktree --help- Git 文档:Git Tools - Multiple Working Trees
- 如何添加可配置多目录 Submodule — 多根目录挂外部仓库
- Agent Skill(devops-skill):
skillsets/devops-skill/git-worktree/— 与 git-workflow / local-workflow 组合的隔离开发流程