写到一半 feature 分支,突然 main 上有紧急 bug 要修。传统流程:
git stashgit checkout main && git checkout -b hotfix- 修完合回
git checkout feature && git stash pop
容易出错(stash 冲突、忘了某些 untracked 文件)。
git worktree 让你在同一个仓库下挂多个 working directory,每个独立
checkout 一个分支。
1. 加一个 worktree
cd ~/repos/myapp # 你正在 feature-x 分支上
git worktree add ../myapp-hotfix main
# Preparing worktree (new branch 'hotfix' from 'main')
# HEAD is now at a1b2c3d Latest main commit
现在 ~/repos/myapp-hotfix/ 是一个完整的工作目录,checkout 在 main 上:
cd ~/repos/myapp-hotfix
git status
# On branch main
# nothing to commit, working tree clean
你的原目录 ~/repos/myapp/ 还在 feature-x 上,没动。
修完 hotfix:
cd ~/repos/myapp-hotfix
git checkout -b hotfix-cve-1234
# 改代码
git commit -am 'fix: CVE-1234'
git push -u origin hotfix-cve-1234
# 开 PR / 合并
完事删 worktree:
cd ~/repos/myapp
git worktree remove ../myapp-hotfix
2. 列出所有 worktree
git worktree list
# /home/me/repos/myapp a1b2c3d [feature-x]
# /home/me/repos/myapp-hotfix e4f5g6h [hotfix-cve-1234]
# /home/me/repos/myapp-review i7j8k9l [pr-42-review]
3. 常用 pattern
A. PR review 不打断当前工作
git worktree add ../myapp-pr42 origin/feature-from-coworker
cd ../myapp-pr42
# review、跑测试、不干扰主工作目录
B. 每个项目固定一个 main worktree
~/repos/myapp/ # 永远 main,用于 git pull / 看 README
~/repos/myapp-dev/ # feature 分支工作目录
~/repos/myapp-pr/ # 任意 review 用
C. 用于 git bisect
bisect 期间不能用工作目录干别的。开 worktree 让 bisect 单独跑,
你继续工作:
git worktree add ../myapp-bisect HEAD
cd ../myapp-bisect
git bisect start
git bisect good v1.0
git bisect bad HEAD
# bisect 在这个 worktree 来回 checkout,不影响主工作目录
4. 用 alias 加速
git config --global alias.wta 'worktree add'
git config --global alias.wtl 'worktree list'
git config --global alias.wtr 'worktree remove'
之后:
git wta ../hotfix main
git wtl
git wtr ../hotfix
5. 替代 multiple clone
老方法是 git clone 同一个 repo 多份:
- 磁盘占用 N 倍
- 不能跨工作目录复用 stash / config / hooks
- 拉新 commit 要在每个 clone 上 pull
worktree 共享同一个 .git/,所有 worktree 共享对象数据库,
拉一次所有 worktree 立即可见。
6. detached HEAD worktree(无分支)
只想 checkout 某个 tag / commit 看看:
git worktree add ../myapp-v1.0 v1.0
# 自动 detached HEAD
完了 git worktree remove ../myapp-v1.0 就清掉。
7. 子目录 + IDE
VSCode / IntelliJ 各开一个窗口指到不同 worktree,能同时调试多个分支
而不互相干扰。
8. CI worktree
CI 想在同一 runner 上并发跑多个分支的测试:
git worktree add /tmp/test-pr-42 origin/pr-42 &
git worktree add /tmp/test-pr-43 origin/pr-43 &
wait
# 然后并行 cd 进去跑测试
避免反复 clone 的开销。
9. lock / unlock
worktree 在外置磁盘 / 网络盘上时,磁盘没挂载 worktree 会被 "automatic
prune"。给它加锁防止:
git worktree lock ../myapp-external --reason 'on external SSD'
git worktree unlock ../myapp-external
10. prune
worktree 目录被手动 rm 但 .git/worktrees/ 里还有元数据:
git worktree prune # 清理孤立元数据
踩过的坑
- 同一个分支不能同时 checkout 到两个 worktree(git 会拒绝)。需要的话
用git worktree add --force或者 detached HEAD 指到分支 tip。 - worktree 在 NTFS / FAT 上:
.git/worktrees/<name>/gitdir的路径用了
绝对路径,跨平台 / 移动后失效。Linux 用就好。 - 在 worktree 里删了文件然后
git stash:stash 是 repo 级别的,主 worktree
也能看到这个 stash。共享 stash 偶尔混淆,建议 stash 加 message 区分。 - 切换 IDE 不会自动重读 worktree —— 关掉 IDE 进程重新打开,
否则 IDE 缓存的 git 状态可能错。
登录后参与评论。