Git Worktree 简单使用

  • 记于:2026-07-19 晚上

背景#

平时用 Git 时,经常会遇到这种情况:

  • 正在一个分支上改需求,改到一半;
  • 突然来了一个线上问题,要先修 hotfix;
  • 或者想同时开两个分支做不同事情;
  • 又或者只是想临时拉一个分支下来看看,不想打断当前目录里的开发状态。

以前我一般会想到两种方式:

  • git stash 之后切分支;
  • 或者直接再 git clone 一份仓库。

这两种方式都能解决问题,但都不算特别舒服。

  • stash 容易打断思路;
  • clone 一份仓库又比较重,尤其是项目比较大时。

这时候 git worktree 就很适合。

这是什么#

git worktree 可以理解为:

  • 同一个 Git 仓库;
  • 同时开多个工作目录;
  • 每个工作目录可以检出不同分支,各自独立开发。

简单说,它不是让你多出多个仓库,而是让你在同一个仓库上同时拥有多个“工作现场”。

比如现在有一个仓库目录:

1
repo/

可以通过 worktree 再额外开两个目录:

1
2
3
repo/
repo-feature-a/
repo-hotfix-login/

这三个目录可以同时存在,并且分别工作在不同分支上。

有什么用#

我觉得它最直接的价值有几个:

  • 不打断当前开发;
  • 不需要频繁 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
2
3
cd ../repo-hotfix-login
git add .
git commit -m "fix: login timeout"

到这里为止,主目录里的开发完全不用动。

3. 回主工作树合并#

这里是一个非常关键的点:

不是“合并 worktree”,而是“合并分支”。

比如我要把刚才的 hotfix 合并回 master

1
2
3
cd ../repo
git switch master
git merge hotfix/login-timeout

如果团队是走 PR 流程,那通常不是本地直接 merge,而是:

1
2
cd ../repo-hotfix-login
git push -u origin hotfix/login-timeout

然后提 PR 到 master

4. 合并后清理#

确认不再需要这个工作树之后,可以清理:

1
2
git worktree remove ../repo-hotfix-login
git branch -d hotfix/login-timeout

如果分支还没合并,git branch -d 会拒绝删除;
只有确认不需要时,才考虑 git branch -D

常用命令#

下面这些是最常用的几个。

查看当前有哪些 worktree#

1
git worktree list

示例输出大概像这样:

1
2
3
/Users/you/code/repo               abc1234 [master]
/Users/you/code/repo-feature-a def5678 [feature/a]
/Users/you/code/repo-hotfix-login 999aaaa [hotfix/login-timeout]

新建 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
2
pwd
# /Users/you/code/repo

当前在 master

1
2
git branch --show-current
# master

现在新开一个 hotfix 工作树:

1
git worktree add -b hotfix/user-status ../repo-hotfix-user-status master

去新目录开发:

1
cd ../repo-hotfix-user-status

改完代码后提交:

1
2
git add .
git commit -m "fix: user status display"

回主目录合并:

1
2
3
cd ../repo
git switch master
git merge hotfix/user-status

最后清理:

1
2
git worktree remove ../repo-hotfix-user-status
git branch -d 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
2
git worktree remove ../repo-feature-login
git branch -d 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
2
* master
+ feature/a

表示:

  • master 是当前目录所在分支;
  • feature/a 正在别的 worktree 中使用。

6. 不建议把长期 worktree 建在主仓库子目录下#

虽然技术上可以这样做,但从目录管理角度看,容易让主目录里出现额外的未跟踪目录,看起来比较乱。

更推荐的结构是:

1
2
3
repo/
repo-feature-a/
repo-hotfix-login/

而不是:

1
2
3
repo/
feat-a/
hotfix-login/

什么时候适合用#

我觉得这些场景特别适合:

  • 正在开发时,突然插入 hotfix;
  • 同时开多个分支并行开发;
  • 想临时验证一个分支,但不想打断当前目录;
  • 项目比较大,不想重复 clone
  • 想同时开多个终端 / IDE 窗口处理不同任务。

如果只是偶尔切一下分支,而且当前目录也很干净,那么直接 git switch 也完全够用。

总结#

git worktree 的核心价值,我觉得一句话就够了:

在同一个仓库里,同时拥有多个独立工作目录,用来并行处理不同分支的开发任务。

如果只想先学会用,那我觉得先记住下面这几条就够了:

1
2
3
4
git worktree list
git worktree add -b hotfix/xxx ../repo-hotfix-xxx master
git worktree remove ../repo-hotfix-xxx
git branch -d hotfix/xxx

另外还有一个最容易记混的点:

  • worktree 是目录;
  • branch 是分支;
  • merge 合并的是分支,不是 worktree。

先把这几个动作顺下来,后面再用几次,基本就熟了。