Git Worktree 简明指南

git worktree 的核心作用:一个 Git 仓库,同时开出多个独立工作目录。每个目录可以停在不同分支,互不打断,适合并行开发、紧急修 bug、PR review、跑多个 agent。


Level 1 · 它到底解决什么问题

普通 Git 工作流里,一个仓库目录一次只能检出一个分支:

cd my-project
git switch main
# 或
git switch feature/payment

如果你正在 feature/payment 上改到一半,突然要修线上 bug,就会遇到三件麻烦事:

  1. 当前改动还没提交
  2. 不能直接切分支
  3. 只能先 stash,修完再 stash pop

典型流程会变成:

git stash
git switch main
git switch -c fix/login-bug
# 修 bug
git switch feature/payment
git stash pop

这不是不能用,但会严重打断思路。

git worktree 的思路是:不要在同一个目录里反复切分支,而是给每个任务一个目录。

例如:

~/code/my-project/                  # main
~/code/my-project-feature-payment/  # feature/payment
~/code/my-project-fix-login/        # fix/login-bug

它们共享同一个 Git 仓库历史,但工作目录彼此独立。


Level 2 · 先看有哪些 worktree

在任意一个 worktree 里执行:

git worktree list

示例:

/home/me/code/my-project                  abc1234 [main]
/home/me/code/my-project-feature-payment  def5678 [feature/payment]
/home/me/code/my-project-fix-login        9988776 [fix/login-bug]

每一行大概是:

路径                                  当前 commit   当前分支

这条命令很重要。只要你忘了自己开过哪些目录,先执行它。


Level 3 · 基于已有分支创建 worktree

如果远程或本地已经有一个分支:

feature/payment

可以创建一个对应的工作目录:

git worktree add ../my-project-feature-payment feature/payment

格式是:

git worktree add <新目录路径> <分支名>

然后进入新目录:

cd ../my-project-feature-payment
git branch --show-current

输出应该是:

feature/payment

从这里开始,你就像在普通仓库里一样开发、提交、推送。


Level 4 · 创建 worktree 的同时新建分支

更常见的场景是:从 main 开一个新分支,并放进新 worktree。

git worktree add -b fix/login-bug ../my-project-fix-login main

格式是:

git worktree add -b <新分支名> <新目录路径> <基于哪个分支>

这条命令等价于三件事:

  1. main 创建 fix/login-bug
  2. 创建目录 ../my-project-fix-login
  3. fix/login-bug 检出到这个目录

进入新目录:

cd ../my-project-fix-login

确认分支:

git branch --show-current

Level 5 · 一个完整日常流程

假设主仓库在:

~/code/my-project

你要修一个登录 bug。

1. 主目录保持在 main

cd ~/code/my-project
git switch main
git pull

2. 创建 bugfix worktree

git worktree add -b fix/login-error ../my-project-fix-login-error main

3. 进入新目录开发

cd ../my-project-fix-login-error

修改代码,跑测试,然后提交:

git status
git add .
git commit -m "fix: handle login error correctly"

4. 推送分支

git push -u origin fix/login-error

然后正常创建 PR。

5. PR 合并后清理

先回到别的目录,不要站在要删除的 worktree 里面删自己:

cd ~/code/my-project

删除 worktree:

git worktree remove ../my-project-fix-login-error

删除本地分支:

git branch -d fix/login-error

如果远程分支也要删:

git push origin --delete fix/login-error

Level 6 · 推荐目录结构

推荐把 worktree 放在主仓库同级目录,而不是主仓库内部。

推荐:

~/code/
  my-project/                    # main
  my-project-feature-payment/     # feature/payment
  my-project-fix-login/           # fix/login-bug
  my-project-review-123/          # review PR #123

不太推荐:

~/code/my-project/
  worktrees/
    fix-login/

原因很简单:放在仓库内部,编辑器、搜索、构建工具、测试工具可能会把里面的文件也扫进去,容易混乱。

目录名最好带上任务含义:

my-project-fix-login
my-project-feature-payment
my-project-refactor-auth
my-project-review-pr-123

不要叫:

test
new
tmp
copy

几天后你会完全忘记它们是什么。


Level 7 · 删除和清理

正常删除:

git worktree remove ../my-project-feature-payment

如果目录里还有未提交改动,Git 会阻止删除。

先检查:

cd ../my-project-feature-payment
git status

确认真的不要了,再强制删除:

git worktree remove --force ../my-project-feature-payment

如果你曾经手动删过目录:

rm -rf ../my-project-old-task

Git 可能还留着一条过期记录。清理它:

git worktree prune

再看列表:

git worktree list

Level 8 · 常见坑

1. 同一个分支不能同时被两个 worktree 使用

如果 main 已经在主目录里被检出:

~/code/my-project  [main]

再执行:

git worktree add ../my-project-main-copy main

可能会报错:

fatal: 'main' is already checked out

这是正常限制:同一个分支默认不能同时在两个 worktree 里检出。

如果只是想临时看一下 main 的内容,可以用 detached 模式:

git worktree add --detach ../my-project-main-copy main

但日常开发不要长期在 detached 状态下工作,容易忘记提交落在哪个分支上。

2. 不要直接 rm -rf 删除 worktree

优先用:

git worktree remove <path>

它会同时清理 Git 内部记录。

如果已经手动删了,再补:

git worktree prune

3. 先确认当前目录和分支

worktree 多了以后,最容易搞错的是:人以为自己在 A 任务,实际终端停在 B 目录。

动手前养成习惯:

pwd
git branch --show-current
git status

Level 9 · 和 clone、stash 的区别

worktree vs clone

你也可以重新 clone 一份仓库:

git clone git@github.com:xxx/my-project.git my-project-copy

但 clone 是完整复制一份仓库。

worktree 是在同一个仓库对象库上开多个工作目录,更轻量,也更适合本机并行分支开发。

方式 特点
git clone 完整复制一份仓库,彼此更独立
git worktree 共享同一份 Git 历史,只增加工作目录

worktree vs stash

场景 更适合
临时切一下分支,改动很少 git stash
同时长期处理多个任务 git worktree
紧急 bugfix,不想打断当前开发 git worktree
同时跑两个分支的项目 git worktree
多个 agent 并行改同一个仓库 git worktree

一句话:

stash 是把当前改动临时收起来;worktree 是给另一个任务直接开一张新桌子。


Level 10 · Agent 场景下为什么常见

很多 coding agent 会用 worktree 做隔离。

根本原因是:如果两个 agent 同时在同一个目录里改文件,它们会互相冲突。一个 agent 改到一半,另一个 agent 也改同一个文件,工作区很快就乱了。

用 worktree 后,可以变成:

repo-agent-task-a/  # agent A 的分支
repo-agent-task-b/  # agent B 的分支
repo-agent-review/  # review 分支

它们共享历史,但文件系统层面互不干扰。每个 agent 在自己的目录里工作,最后通过 Git merge / rebase / PR 来合并结果。

所以在多 agent、后台任务、自动修 CI、并行实验这些场景里,worktree 是很自然的基础设施。


常用命令速查

查看所有 worktree:

git worktree list

基于已有分支创建 worktree:

git worktree add ../my-project-feature feature/payment

创建 worktree 的同时新建分支:

git worktree add -b feature/payment ../my-project-feature-payment main

删除 worktree:

git worktree remove ../my-project-feature-payment

强制删除:

git worktree remove --force ../my-project-feature-payment

清理过期记录:

git worktree prune

查看当前分支:

git branch --show-current

最小心智模型

记住三句话就够了:

  1. git worktree 让一个仓库同时拥有多个工作目录。
  2. 每个 worktree 通常对应一个分支,适合一个任务一个目录。
  3. 创建用 git worktree add,结束用 git worktree remove,别直接 rm -rf

最常用的命令是:

git worktree add -b <branch> <path> <base>
git worktree list
git worktree remove <path>

如果你经常在多个分支之间来回切,或者需要并行处理多个任务,worktree 通常比反复 checkout + stash 更清楚。