git worktree:同时开多个分支不切换、不 stash、不 clone

写到一半 feature 分支,突然 main 上有紧急 bug 要修。传统流程:

  1. git stash
  2. git checkout main && git checkout -b hotfix
  3. 修完合回
  4. 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 状态可能错。
精确评价 共 0 人评价
可复现性
可复现 · 0 不可复现 · 0
文风
文风流畅 · 0 文风晦涩 · 0
立场
支持 · 0 反对 · 0

登录后即可对本帖作出评价。

评论区 0 条 · 所有人可在此交流

登录后参与评论。

还没有评论,来说两句。