TL;DR(60 秒速览)
- 是什么:为同一个仓库创建多个“工作区”(工作副本),每个工作区可检出不同分支/提交,同时开发互不干扰。
- 核心约束:同一分支同一时刻只能在一个 worktree 被检出;要并行就用不同分支或
--detach
。 - 典型场景:并行开发与热修、跨版本回溯与验证、长分支隔离、大仓多版本并行编译、评审验证临时环境。
- 相对切分支/多仓 clone 的优势:切换成本低、索引/对象共享省磁盘、避免频繁
stash
、误操作风险更小。 - 最常用命令:
git worktree list
、git worktree add
、git worktree remove
、git worktree prune
、git worktree lock|unlock
、git worktree move
、git worktree repair
。
什么是 git worktree(工作原理速读)
git worktree
允许一个 Git 仓库(共享 .git/objects
与索引)同时拥有多个可独立操作的工作目录。每个工作区都像一个“轻量级的独立仓库”,但它们共享底层对象库,减少磁盘占用并加速切换。
关键约束:同一分支在同一时刻只能在一个 worktree 中被检出。如果想在多个 worktree 同时基于同一点进行试验,可使用不同分支名,或使用 --detach
直接检出到某个提交。
使用场景(配简短示例)
- 并行开发与热修分离:主工作区做新功能,另起一个 worktree 用于线上热修。
- 示例:在修复
release/1.5
的同时,主区继续main
上的开发。
- 示例:在修复
- 跨版本回溯/复现问题:为老版本创建独立工作区,快速拉起构建与测试,避免污染当前开发目录。
- 长生命周期分支隔离:复杂重构或实验性优化放在独立 worktree,远离日常目录与依赖环境。
- 大仓多版本并行编译:同一 monorepo 多分支同时编译,复用对象库而非多次 clone,节省磁盘与 I/O。
- 代码评审/验证专用工作区:为某个 PR/提交开临时工作区,拉代码、跑验证,用完即可清理。
要点回顾:
- 并行不打扰、共享更省磁盘、切换无需 stash。
它解决了什么问题(痛点 → 方案 → 为什么更好)
- 传统做法 A:在一个目录里频繁切换分支 +
stash
- 痛点:上下文切换重、容易漏
stash
或冲突、临时文件污染。 - worktree:为每条工作流给一个目录,互不影响,无需频繁
stash
。
- 痛点:上下文切换重、容易漏
- 传统做法 B:为每个并行任务再
git clone
一个仓库- 痛点:占用更多磁盘/网络,重复索引,初次安装依赖/编译开销大。
- worktree:共享对象库和索引,创建/切换更快,磁盘占用更低。
- 误操作与风险控制
- 痛点:在同一目录误提交/误合并、回不去当前状态。
- worktree:语义化目录区分任务,降低误操作;支持
lock
保护关键工作区。
要点回顾:
- 相对“切分支+stash”更安全,相对“多仓 clone”更高效、更省空间。
常用命令速查(附何时使用)
注:示例以 macOS/Linux 为主,Windows 请将路径替换为合适的位置。
查看与总览
# 查看所有工作区
git worktree list
# Porcelain 模式(脚本友好)
git worktree list --porcelain
适用:需要清查当前有哪些 worktree、各自绑定分支与路径。
创建工作区(新增目录)
# 基于 main 新建分支并创建工作区目录
git fetch origin
git worktree add ~/code/myrepo/.wt/feature-login -b feature/login origin/main
# 基于已有本地分支创建工作区
git worktree add ~/code/myrepo/.wt/release-1-5 release/1.5
# 只临时查看某个提交(分离头指针,不占用分支)
git worktree add --detach ~/code/myrepo/.wt/tmp-check 4f1e2c3
适用:并行开发、热修、临时复现/排查。
提示:若远端存在但本地无分支,先创建本地追踪分支更稳妥:
git fetch origin release/1.5:release/1.5
git worktree add ~/code/myrepo/.wt/release-1-5 release/1.5
清理与删除
# 预演清理(只显示将被清理的内容)
git worktree prune -n -v
# 实际清理无效/残留的 worktree 记录
git worktree prune
# 删除某个工作区目录(先确保其中无未跟踪变更)
git worktree remove ~/code/myrepo/.wt/feature-login
# 强制删除(有风险:可能丢弃未提交的改动)
git worktree remove -f ~/code/myrepo/.wt/feature-login
适用:回收空间、合并完成后的收尾。使用 -f/--force
前务必确认无未保存改动。
保护与迁移
# 锁定工作区,避免被误删或清理;可附原因
git worktree lock ~/code/myrepo/.wt/release-1-5 --reason "hotfix in progress"
# 取消锁定
git worktree unlock ~/code/myrepo/.wt/release-1-5
# 移动工作区到新位置(路径变更)
git worktree move ~/code/myrepo/.wt/feature-login ~/code/myrepo/.wt/feature-auth
# 修复(当仓库整体路径被移动后,修复内部链接)
git worktree repair
适用:保护关键分支、调整磁盘布局、迁移仓库后修复链接。
要点回顾:
- 创建用
add
,收尾用remove
/prune
,保护用lock
,迁移用move
,路径变更后用repair
。
快速上手(可复制的最短路径)
建议目录约定:在仓库根目录旁建立 .wt/
作为所有 worktree 的容器,便于统一管理与清理。
# 1) 进入主仓库目录
cd ~/code/myrepo
# 2) 并行开发一个功能分支
git fetch origin
git worktree add ~/code/myrepo/.wt/feature-x -b feature/x origin/main
# 3) 同时拉起一个热修分支
git fetch origin release/1.5:release/1.5
git worktree add ~/code/myrepo/.wt/release-1-5 release/1.5
# 4) 验证完成后,安全收尾
git -C ~/code/myrepo/.wt/feature-x push origin feature/x
git worktree remove ~/code/myrepo/.wt/feature-x
git worktree prune -n -v && git worktree prune
要点回顾:
.wt/
目录集中管理;-C
可直接对目标工作区执行 Git 命令。
常见坑与排查
- “
branch '<name>' already checked out
”- 原因:同一分支已在其他 worktree 检出。
- 解决:改用不同分支名(如从
origin/main
新建feature/x
),或使用--detach
;不要强行在多个 worktree 同时检出同一分支。
- “worktree is locked”/残留锁文件
- 解决:确认无正在使用后,
git worktree unlock <path>
;若异常终止后状态紊乱,可尝试git worktree repair
再prune
。
- 解决:确认无正在使用后,
remove
vsprune
remove
删除指定路径的工作区;prune
清理无效/残留的工作区记录(例如目录已被手动删掉)。
- 强制删除风险
git worktree remove -f
可能丢弃未提交改动。优先提交或用git stash
保存,再删除。
要点回顾:
- 分支绑定是硬约束;收尾与清理要有序;遇到异常先
unlock/repair/prune
。
日常开发使用总结(可落地清单)
- 并行开发:每个功能一个工作区
- 新建:
git worktree add ~/code/repo/.wt/feature-foo -b feature/foo origin/main
- 推送:
git -C ~/code/repo/.wt/feature-foo push -u origin feature/foo
- 收尾:
git worktree remove ~/code/repo/.wt/feature-foo && git worktree prune
- 新建:
- 线上热修:主线不打断
- 准备:
git fetch origin release/1.5:release/1.5
- 新建:
git worktree add ~/code/repo/.wt/release-1-5 release/1.5
- 保护:
git worktree lock ~/code/repo/.wt/release-1-5 --reason "hotfix"
- 准备:
- 回溯调试/复现:不污染当前目录
- 临时:
git worktree add --detach ~/code/repo/.wt/tmp 4f1e2c3
- 用完:
git worktree remove ~/code/repo/.wt/tmp
- 临时:
- 评审验证:拉起 PR 对应提交做本地验证
git fetch origin pull/123/head:pr-123 && git worktree add ~/code/repo/.wt/pr-123 pr-123
要点回顾:
- 工作区即工作单元;命名规范、集中目录、用完即清理。
与相关概念的边界(何时不用 worktree)
- 与多仓
clone
:当需要完全隔离的.git
历史与配置(如不同 hooks、不同全局设置)时,仍可选择多仓。 - 与
sparse-checkout
:前者解决“多个并行工作区”,后者解决“单工作区的目录稀疏检出”,二者可组合使用但关注点不同。 - 与
submodule/subtree
:面向多仓协作关系的组织方式,非 worktree 的替代关系。
参考链接
- Git 官方文档:
https://git-scm.com/docs/git-worktree
- Pro Git 书籍相关章节:
https://git-scm.com/book/zh/v2
- 关于 prune/repair 的讨论:
https://lore.kernel.org/git/
结语
当你需要同时处理多个任务分支、又不想在单个目录里频繁切分支与 stash
时,git worktree
是更优雅与高效的选择。以目录命名规范化、集中清理策略和少量惯例,即可把它稳定地纳入你的日常工作流。