多工作区(Worktree)
本教程共 26 篇 · 第 22 篇 · 更新于 2026-07-29 · 约 5 分钟阅读
22. 多工作区(Worktree)
本节目标:学会用 git worktree 在同一台机器上同时操作一个仓库的多个分支,告别频繁 stash 和切换分支的烦恼。
为什么需要 Worktree
你正在 main 分支上写新功能。突然线上报了个紧急 bug,需要立刻切去修。
要么stash当前工作切分支,要么 commit 一个半成品。两种都让人不爽。
Worktree 给你第三条路:新建一个目录,在另一个分支上工作,两个目录互不干扰。
它们共享同一个 .git 目录,只是工作目录不同。
Worktree 的原理
一个 Git 仓库默认有一个工作区(worktree)。git worktree 允许你为同一个仓库创建多个工作区。
- 所有 worktree 共享同一个
.git目录(对象数据库、引用、配置) - 每个 worktree 有独立的工作目录、暂存区和 HEAD
- 同一时间,一个分支只能被一个 worktree 检出
可以理解为:同一个仓库的多个”分身”,各干各的活。
基本命令
创建 Worktree
基于当前分支新建一个 worktree:
git worktree add ../hotfix-dir hotfix/bug-123
这会在 ../hotfix-dir 目录检出 hotfix/bug-123 分支(如果不存在则自动创建)。
也可以基于现有分支创建:
git worktree add ../review-dir feature/login
列出所有 Worktree
git worktree list
/home/user/project a1b2c3d [main]
/home/user/hotfix-dir e4f5g6h [hotfix/bug-123]
/home/user/review-dir i7j8k9l [feature/login]
移除 Worktree
git worktree remove ../hotfix-dir
如果 worktree 里有未提交的修改,命令会拒绝删除。加 -f 可以强制删除:
git worktree remove -f ../hotfix-dir
清理无效 Worktree
有时候目录被手动删了,但 Git 还记着它。执行:
git worktree prune
与 git clone 的区别
遇到需要同时处理多个分支的场景,传统做法是 git clone 一份新仓库。
| 对比项 | git clone | git worktree |
|---|---|---|
| 磁盘占用 | 完整复制所有对象 | 共享对象数据库 |
| 网络消耗 | 需要重新拉取 | 零网络开销 |
| 仓库隔离 | 完全独立 | 共享配置和引用 |
| 同步 | 需要 push/pull | 实时共享 |
| 垃圾回收 | 各自独立 | 共享 |
当你需要在同一个仓库的不同分支上同时工作时,worktree 是比 clone 更好的选择。
Tip同一分支不能在两个 worktree 同时检出。Git 会拒绝这种操作并报错。
实用场景
场景一:紧急修复线上 bug
你在 feature/payment 分支开发到一半。线上出 bug 了:
git worktree add ../hotfix main
cd ../hotfix
# 修 bug,提交,推送
git commit -am "修复线上 bug"
git push origin main
回到原目录继续写你的 feature。
场景二:代码审查
同事发了 PR 让你 review。你不想弄脏当前工作区:
git worktree add ../review feature/login
cd ../review
# 看代码,跑测试
review 完直接 git worktree remove ../review 清理。
场景三:同时跑多个环境的测试
比如需要对比某个功能在不同分支的表现,或者一边开发一边跑耗时很长的测试套件。
Git 2.55 的 exclude 共享
Git 2.55 改进了 git-ls-files 在 worktree 环境中对 exclude 规则的处理。需要注意的是,.git/info/exclude 一直位于主仓库的 .git 目录中,因此一直是共享的;而每个 worktree 可以通过 .git/worktrees/<名字>/info/exclude 维护自己独立的忽略规则。
之前每个 worktree 可能各自维护一份忽略规则,容易不一致。2.55 之后这个问题解决了。
注意事项
- 同一分支不能在两个 worktree 同时检出
git worktree add ../another main
# fatal: 'main' is already checked out at /home/user/project
-
worktree 之间共享引用(refs)。在一个 worktree 创建分支,另一个 worktree 能立即看到。
-
不要手动修改
.git目录下的 worktree 相关文件。用命令操作就好。
Warning手动改
.git目录下的 worktree 文件,可能导致仓库损坏。所有操作请用git worktree命令。
git worktree list能看出哪个是主 worktree(第一个列出的就是)。
实际操作演示
# 当前位置在 main 分支,且有未完成的修改
git status
# Changes not staged for commit...
# 创建 worktree 去修紧急 bug
git worktree add ../urgent-fix main
# 进入新目录
cd ../urgent-fix
# 修复 bug
echo "修复内容" > fix.txt
git add fix.txt
git commit -m "紧急修复"
git push origin main
# 回到原目录继续工作
cd ../project
git status # 你的修改还在,不受影响
# 用完清理
git worktree remove ../urgent-fix
其他有用的子命令
移动 worktree 目录:
git worktree move ../hotfix-dir ../new-location
锁定 worktree(防止被意外删除,适合长期使用的 worktree):
git worktree lock ../review-dir
git worktree unlock ../review-dir
查看 worktree 是否被锁定或有未提交的修改:
git worktree list --porcelain
一句话总结:worktree 让一个仓库有多个分身。需要并行处理多个分支时,比 clone 更快、更省空间。
这章学到了什么
- worktree 让同一仓库拥有多个工作区,共享 .git 目录但工作目录独立
- 基本命令:
add创建、remove删除、list查看、prune清理无效记录 - 与 clone 相比,worktree 共享对象数据库、零网络开销、实时共享
- 同一分支不能在两个 worktree 同时检出
- 实用场景:紧急修复线上 bug、代码审查、同时跑多个环境的测试
下一章,我们学习如何在 Git 操作的关键节点插入自定义脚本——钩子。