1. 核心概念
git worktree 允许在同一个 Git 仓库下同时检出多个分支到不同目录,避免频繁 stash/checkout 切换上下文。
main-repo/ ← 主工作目录(如 main)
├── .git/ ← 唯一的 Git 对象库(所有 worktree 共享)
└── ...
../feature-login/ ← worktree 1(独立目录,检出 feature/login)
../hotfix-urgent/ ← worktree 2(独立目录,检出 hotfix/urgent)
- 一个
.git数据库,多个工作目录:所有 worktree 共享对象库、ref、config - 每个 worktree 绑定唯一分支:同一分支不能同时被两个 worktree 检出
- 完全独立的暂存区和工作区:互不干扰,无需 stash
2. 创建 Worktree
基本语法
bash
git worktree add <路径> <分支名>
常见场景
| 场景 | 命令 | 说明 |
|---|---|---|
| 检出现有分支 | git worktree add ../feature-login feature/login |
最常用 |
| 创建新分支并检出 | git worktree add -b feature/login ../feature-login main |
基于 main 新建分支 |
| 基于远程分支创建 | git worktree add ../hotfix origin/hotfix/urgent |
自动跟踪远程分支 |
| 临时调试(detached HEAD) | git worktree add --detach ../debug-temp abc1234 |
不绑定分支,排查问题用 |
💡 路径建议 :将 worktree 放在主仓库的同级目录 而非子目录内,避免被主仓库的
.gitignore或构建工具误扫描。
3. 日常使用
在 worktree 中正常工作
进入对应目录后,所有 Git 操作与主仓库完全一致:
bash
cd ../feature-login
git status # 只反映当前 worktree 的状态
git add / commit / push / pull # 正常操作
npm install / mvn compile # 独立构建,不影响主目录
查看所有 worktree
bash
git worktree list
输出示例:
/home/user/project abc1234 [main]
/home/user/feature-login def5678 [feature/login]
/home/user/hotfix-urgent ghi9012 [hotfix/urgent]
⚠️ 关键限制
- 同一分支不能被两个 worktree 同时检出(会报错)
- 每个 worktree 有独立的 index(暂存区) ,
git add只影响当前目录 - submodule 不会自动初始化,需在每个 worktree 中手动
git submodule update --init
4. 删除 Worktree
正确删除流程
bash
# 1. 先删除工作目录(或直接 rm -rf)
rm -rf ../feature-login
# 2. 清理 worktree 元数据(必须!)
git worktree prune
一步到位(推荐,Git 2.17+)
bash
git worktree remove ../feature-login
⚠️ 切勿只删目录不 prune :残留元数据会导致
git worktree list显示幽灵条目,后续创建同名路径时出错。
分支处理
- 删除 worktree 不会删除分支
- 若该分支已合并且不再需要,单独删除:
git branch -d feature/login
5. 维护与最佳实践
定期健康检查
bash
# 检查是否有失效的 worktree 引用
git worktree list --porcelain | grep -c "prunable"
# 自动修复
git worktree prune -v
IDE / 编辑器配置
- 每个 worktree 应作为独立项目打开,不要在一个窗口中混合多个 worktree
node_modules、target、.venv等构建产物需在各 worktree 中独立安装- VS Code 推荐使用 "Add Folder to Workspace" 管理多个 worktree
CI / 脚本注意事项
- 脚本中避免硬编码路径,使用
git rev-parse --show-toplevel获取当前 worktree 根目录 git worktree内的GIT_DIR指向.git/worktrees/<name>/,而非主.git/
与 filter-repo 的兼容性
- 执行
git filter-repo前必须先删除所有 worktree - 重写完成后重新创建 worktree(旧 worktree 引用的 commit hash 已失效)
6. 常见问题:远程分支与本地分支冲突
❓ 本地已有 test 分支,能否基于 origin/test 再建 worktree?
不能直接检出同名分支。 Git worktree 的硬性规则:同一分支引用在同一时刻只能被一个工作目录检出。
text
fatal: 'test' is already checked out at '/path/to/main-repo'
✅ 正确做法:创建不同名的新分支
只要新 worktree 检出的本地分支名 与已检出的 test 不同,就不会有任何冲突。远程 origin/test 只是只读跟踪引用,不参与唯一性约束检查。
bash
# 基于 origin/test 创建新分支 my-test-fix,并在新 worktree 中检出
git worktree add ../my-test-fix -b my-test-fix origin/test
执行后状态:
| 工作目录 | 检出的本地分支 | 追踪的远程分支 | 是否冲突 |
|---|---|---|---|
| 主仓库 | test |
origin/test |
--- |
../my-test-fix |
my-test-fix |
origin/test(自动设置上游) |
✅ 无冲突 |
其他替代方案
| 方案 | 命令 | 适用场景 |
|---|---|---|
| Detached HEAD | git worktree add --detach ../test-temp origin/test |
临时查看/测试,无需提交 |
| 移动现有分支 | 先 git checkout main,再 git worktree add ../test-work test |
让新 worktree 接管原分支 |
⚠️ 特别提醒 :不要尝试手动修改
.git/worktrees/下的元数据来绕过唯一性限制。这会导致多个 worktree 同时写入同一个 ref 文件,造成索引损坏和历史混乱。
7. Worktree vs 其他方案对比
| 方案 | 磁盘占用 | 切换速度 | 并行开发 | 适用场景 |
|---|---|---|---|---|
git checkout |
最低 | 慢(大项目) | ❌ | 简单串行开发 |
git stash |
最低 | 中 | ❌ | 临时保存修改 |
git clone 多份 |
高(N倍) | 快 | ✅ | 完全隔离环境 |
git worktree |
低(共享对象库) | 即时 | ✅ | 多分支并行开发(推荐) |
8. 速查清单
bash
# 创建
git worktree add ../my-feature -b feature/my-feature main
# 基于远程分支创建(不与本地同名分支冲突)
git worktree add ../my-test-fix -b my-test-fix origin/test
# 使用
cd ../my-feature && git status && npm test
# 查看
git worktree list
# 删除
git worktree remove ../my-feature
# 维护
git worktree prune -v