Appearance
Git Worktree 多工作目录开发实践
- 状态:已验证
- 来源:对话整理
- 更新时间:2026-03-12
关键结论
git worktree允许一个 Git 仓库同时挂载多个工作目录,适合并行开发多个分支。- 常见开发实践中,一个 worktree 对应一个独立分支;同一分支同一时刻只能被一个 worktree 检出。
- 如果某个分支已经被当前仓库或其他 worktree 检出,再执行
git worktree add绑定该分支时会报fatal: '<branch>' is already used by worktree。 git worktree add -b用于创建新分支并立即生成对应的 worktree,git worktree add则用于检出现有分支。- 多个 worktree 共享主仓库的对象数据库,不会完整复制一份仓库。
- 对编译型项目尤其有效,例如嵌入式 SDK、大型 C/C++ 工程,可避免频繁
checkout导致编译缓存失效。 - 本条目只讲多工作目录的创建、占用和清理,不展开分支删除 warning、远程跟踪分支或
switch/restore的语义。
详细分析
- 在大型仓库中频繁执行
git checkout,容易打断当前工作目录状态,也可能让基于目录的构建缓存失效。 git worktree会在主仓库的.git/worktrees/下维护附加工作目录的元数据,新工作目录中的.git通常只是一个指向主仓库内部路径的文本文件。- worktree 共享的是对象数据库和仓库元数据,不是复制整个仓库,因此磁盘开销通常明显低于重新克隆一份仓库。
- 对需要同时维护发布分支、功能分支、问题修复分支的场景,worktree 比单工作区反复切换更稳定,未提交改动也更不容易互相污染。
- 可以把
git worktree add -b <new-branch> <path> <start-point>理解为“创建分支 + 创建独立工作目录”两个动作的一次性组合。 - 如果主仓库当前就在
shangyun分支上,再执行git worktree add ../shangyun shangyun,Git 会拒绝,因为shangyun已经被主仓库这个 worktree 使用。 - 这种限制本质上是在保证“一个分支只对应一个 worktree”,避免多个工作目录同时推进同一个分支 HEAD,导致引用状态和索引语义混乱。
- 如果你正在排查“分支删除时为什么提示
merged to remote but not HEAD”,应查看 branch.md;如果你只是在决定是用checkout还是switch,应查看 checkout-switch-restore.md。
可执行步骤
- 在主仓库确认当前状态正常,并决定新 worktree 的目录位置。
- 使用
git worktree list检查当前所有 worktree 的路径、分支和状态,确认目标分支没有被占用。 - 如果要为新分支创建 worktree,执行
git worktree add -b stream ../sdk_stream master。 - 如果分支已经存在,执行
git worktree add ../sdk_webrtc xm_webrtc。 - 如果命中
fatal: '<branch>' is already used by worktree,先在主仓库切换到其他分支,例如git checkout master或git switch master。 - 再次执行
git worktree add ../sdk_shangyun shangyun创建目标 worktree。 - 在各自工作目录中独立开发、编译和提交,互不影响。
- 不再使用时先确认改动已处理,再执行
git worktree remove ../sdk_stream。 - 如果 worktree 被手工移动、删除或路径记录异常,执行
git worktree repair;必要时再执行git worktree prune清理失效记录。
命令 / 配置 / 代码
创建新分支并生成 worktree:
bash
git worktree add -b stream ../sdk_stream master说明:
- 基于
master创建新分支stream。 - 同时把
stream检出到新目录../sdk_stream。 - 适合“准备从某个基线拉出一个新开发分支,并立刻开始独立开发”的场景。
为已有分支创建 worktree:
bash
git worktree add ../sdk_webrtc xm_webrtc说明:
- 直接使用已有分支
xm_webrtc。 - 把该分支检出到目录
../sdk_webrtc。 - 不会创建新分支;如果分支不存在且未加
-b,命令会报错。
分支已被其他 worktree 使用时的典型报错:
bash
git worktree add ../shangyun shangyun
fatal: 'shangyun' is already used by worktree at '/repo'说明:
- 表示分支
shangyun已经被当前主仓库或其他 worktree 检出。 - 常见处理方式是先把主仓库切换到
master或main,再重新执行git worktree add。
冲突处理示例:
bash
git checkout master
git worktree add ../sdk_shangyun shangyuntext
repo
├── .git
│ └── worktrees
│ ├── stream
│ └── webrtc
└── src
sdk_stream
├── .git
└── srctext
gitdir: /repo/.git/worktrees/sdk_stream查看当前 worktree:
bash
git worktree list说明:
- 列出当前仓库下所有 worktree 的路径、对应分支和状态。
- 适合在清理、排错或确认目录绑定关系前先做检查。
删除不再使用的 worktree:
bash
git worktree remove ../sdk_stream说明:
- 正常移除指定 worktree 目录,并同步清理 Git 记录的 worktree 元数据。
- 适合在分支任务结束后回收目录,避免直接手动删目录留下脏记录。
清理失效 worktree 记录:
bash
git worktree prune说明:
- 清理已经失效或目录已不存在的 worktree 元数据记录。
- 常用于手动删过目录、迁移目录失败或历史记录残留的场景。
修复 worktree 路径记录:
bash
git worktree repair说明:
- 重新修复主仓库与 worktree 之间的路径关联信息。
- 适合 worktree 被移动、复制后路径记录异常,或 Git 提示 worktree 状态不一致时使用。
风险与注意事项
- 同一分支不能被多个 worktree 同时检出;如果需要并行处理,应新建分支或调整工作方式。
- 创建 worktree 前建议先执行
git worktree list,确认目标分支没有被当前仓库或其他 worktree 占用。 - 主仓库通常保持在
master或main这类基线分支,更方便为业务分支单独拆出 worktree。 - 如果目标分支尚不存在且未使用
-b参数,git worktree add会直接报错。 - 不要直接删除 worktree 目录,应优先使用
git worktree remove清理元数据。 - 子模块不会因为新增 worktree 自动完成初始化,进入对应目录后仍需单独执行子模块初始化或更新。
- 如果曾经手工删除目录,可能残留失效记录,需要用
git worktree prune或git worktree repair修复。
关联条目
- 分支删除 warning 与
HEAD判定见 Git 删除本地分支出现 "merged to remote but not HEAD" 的含义。 - 分支切换与文件恢复命令的职责拆分见 Git checkout、switch 与 restore 的用法与区别。