- 记于:2026-07-19 晚上
背景#
平时用 Git 时,经常会遇到这种情况:
- 正在一个分支上改需求,改到一半;
- 突然来了一个线上问题,要先修 hotfix;
- 或者想同时开两个分支做不同事情;
- 又或者只是想临时拉一个分支下来看看,不想打断当前目录里的开发状态。
以前我一般会想到两种方式:
git stash之后切分支;- 或者直接再
git clone一份仓库。
这两种方式都能解决问题,但都不算特别舒服。
stash容易打断思路;- 多
clone一份仓库又比较重,尤其是项目比较大时。
这时候 git worktree 就很适合。
这是什么#
git worktree 可以理解为:
- 同一个 Git 仓库;
- 同时开多个工作目录;
- 每个工作目录可以检出不同分支,各自独立开发。
简单说,它不是让你多出多个仓库,而是让你在同一个仓库上同时拥有多个“工作现场”。
比如现在有一个仓库目录:
1 | repo/ |
可以通过 worktree 再额外开两个目录:
1 | repo/ |
这三个目录可以同时存在,并且分别工作在不同分支上。
有什么用#
我觉得它最直接的价值有几个:
- 不打断当前开发;
- 不需要频繁
stash; - 不需要重复
clone大仓库; - 可以同时打开多个 IDE 窗口,分别处理不同任务;
- 很适合 hotfix、临时验证、并行开发。
比如我正在 master 上看代码,突然要修一个登录超时问题。
这时候没必要先把当前目录折腾一遍,直接新开一个 hotfix 工作树就行。
核心理解#
我觉得学 git worktree,先记住下面这几点就够了。
1. worktree 是“工作目录”,不是“分支”#
worktree 只是一个额外的工作区目录。
真正承载提交历史的,还是 Git 分支。
所以:
- 开新 worktree,本质上通常也是顺手开一个新分支;
- 改完后提交,也是提交到这个分支;
- 后续合并时,合并的是“分支”,不是“工作树目录”。
2. 它解决的是“并行开发”,不是“完全隔离”#
多个 worktree 共享同一个仓库的大部分 Git 数据。
比如提交对象、分支引用、远程信息这些,底层是共享的。
所以它更像:
- 一个仓库底座;
- 多个并行工作目录。
但它不是多个完全独立的 clone。
3. 每个 worktree 都有自己的检出状态#
这意味着:
- 当前目录可以是
master - 另一个目录可以是
hotfix/login-timeout - 再另一个目录可以是
feature/payment
它们互不打断,各自改各自的。
常见流程(重点)#
这一部分我觉得最重要,先学会用,再去记别的。
1. 新开一个工作树#
比如现在主目录在 master,我想单独开一个 hotfix 目录:
1 | git worktree add -b hotfix/login-timeout ../repo-hotfix-login master |
这条命令的意思是:
- 在
../repo-hotfix-login创建一个新的工作目录; - 新建分支
hotfix/login-timeout; - 这个分支从
master切出来; - 并且在新目录里检出这个分支。
2. 去新目录里开发并提交#
1 | cd ../repo-hotfix-login |
到这里为止,主目录里的开发完全不用动。
3. 回主工作树合并#
这里是一个非常关键的点:
不是“合并 worktree”,而是“合并分支”。
比如我要把刚才的 hotfix 合并回 master:
1 | cd ../repo |
如果团队是走 PR 流程,那通常不是本地直接 merge,而是:
1 | cd ../repo-hotfix-login |
然后提 PR 到 master。
4. 合并后清理#
确认不再需要这个工作树之后,可以清理:
1 | git worktree remove ../repo-hotfix-login |
如果分支还没合并,git branch -d 会拒绝删除;
只有确认不需要时,才考虑 git branch -D。
常用命令#
下面这些是最常用的几个。
查看当前有哪些 worktree#
1 | git worktree list |
示例输出大概像这样:
1 | /Users/you/code/repo abc1234 [master] |
新建 worktree,并创建新分支#
1 | git worktree add -b feature/a ../repo-feature-a master |
基于已有分支创建 worktree#
1 | git worktree add ../repo-release release/1.0 |
删除 worktree#
1 | git worktree remove ../repo-feature-a |
清理失效记录#
如果你手工删过目录,Git 里可能还留着 worktree 记录,这时可以:
1 | git worktree prune |
一个完整示例#
这里写一个我觉得最适合刚开始上手的完整流程。
假设当前目录是主仓库:
1 | pwd |
当前在 master:
1 | git branch --show-current |
现在新开一个 hotfix 工作树:
1 | git worktree add -b hotfix/user-status ../repo-hotfix-user-status master |
去新目录开发:
1 | cd ../repo-hotfix-user-status |
改完代码后提交:
1 | git add . |
回主目录合并:
1 | cd ../repo |
最后清理:
1 | git worktree remove ../repo-hotfix-user-status |
如果是团队协作场景,那就是把中间的本地合并步骤换成 push + PR。
注意点#
这部分很重要,实际使用时比较容易踩坑。
1. git worktree add 的第一个核心参数是“路径”#
比如:
1 | git worktree add feat-a |
这里的 feat-a 会被 Git 当成“目录路径”。
如果当前就在仓库目录里执行,那么 Git 会直接在当前目录下面创建一个 feat-a/ 子目录。
如果同时自动创建了同名分支,那么最终效果通常就是:
- 当前目录下多出一个
feat-a/ - 新 worktree 使用分支
feat-a
这个行为本身没问题,但一般不够清爽。
更推荐直接建成同级目录:
1 | git worktree add -b feat-a ../repo-feat-a master |
2. git worktree remove 删除的是“工作树路径”,不是“分支名”#
例如下面这种写法:
1 | git worktree remove feature/login |
如果 feature/login 只是分支名,而不是工作树目录路径,那么就会报错。
正确思路应该是:
1 | git worktree remove ../repo-feature-login |
也就是:
remove删除工作树目录branch -d删除分支
3. 删除 worktree 后,分支默认还在#
这点也很容易忽略。
比如:
1 | git worktree remove ../repo-feature-a |
执行完后:
- worktree 目录没了;
- 但
feature/a分支通常还在。
如果这个分支后面不需要了,还得再手动删分支。
4. 同一个分支不能同时在多个 worktree 里检出#
比如 feature/a 已经在某个 worktree 中打开了,那么一般不能再在另一个 worktree 中同时检出同一个本地分支。
这个限制本身是合理的,主要是为了避免混乱。
5. git branch 里的 + 表示该分支正在别的 worktree 中被检出#
这个细节顺手记一下也挺有用。
比如:
1 | * master |
表示:
master是当前目录所在分支;feature/a正在别的 worktree 中使用。
6. 不建议把长期 worktree 建在主仓库子目录下#
虽然技术上可以这样做,但从目录管理角度看,容易让主目录里出现额外的未跟踪目录,看起来比较乱。
更推荐的结构是:
1 | repo/ |
而不是:
1 | repo/ |
什么时候适合用#
我觉得这些场景特别适合:
- 正在开发时,突然插入 hotfix;
- 同时开多个分支并行开发;
- 想临时验证一个分支,但不想打断当前目录;
- 项目比较大,不想重复
clone; - 想同时开多个终端 / IDE 窗口处理不同任务。
如果只是偶尔切一下分支,而且当前目录也很干净,那么直接 git switch 也完全够用。
总结#
git worktree 的核心价值,我觉得一句话就够了:
在同一个仓库里,同时拥有多个独立工作目录,用来并行处理不同分支的开发任务。
如果只想先学会用,那我觉得先记住下面这几条就够了:
1 | git worktree list |
另外还有一个最容易记混的点:
- worktree 是目录;
- branch 是分支;
- merge 合并的是分支,不是 worktree。
先把这几个动作顺下来,后面再用几次,基本就熟了。


















