git worktree 是物理隔离多分支工作区的机制,共享同一.git库;常用命令如 git worktree add ../fix-login fix/login 关联本地分支,或 git worktree add ../feat-pay origin/feat/payment 拉取远程分支。

git worktree 不是用来替代 stash 或 branch 切换的,它是让你在物理上隔离多个分支工作区的机制——每个目录独立 checkout、独立编辑、互不干扰,但共享同一个 .git 对象库。
怎么创建新工作区并关联分支
最常用的是基于已有本地分支或远程分支拉出一个新目录:
-
git worktree add ../fix-login fix/login:在上级目录建fix-login文件夹,并检出本地分支fix/login -
git worktree add ../feat-pay origin/feat/payment:自动 fetch 远程分支后检出,适合团队协作中直接基于最新远程状态开发 -
git worktree add -b feat/new-ui ../ui-branch:分支不存在时,自动创建并检出,-b后面是分支名,路径末尾名只是目录名,不强制一致
注意:git worktree add 默认不会自动 git pull,新建工作区的 HEAD 指向的是执行命令时该分支的当前 commit,不是实时远程最新。
为什么 git status 在主目录里会报 “Unmerged paths”
这是 worktree 最容易被忽略的冲突信号,本质是 Git 试图统一管理所有工作区的 index 和暂存状态。触发条件很具体:
- 两个 worktree 同时修改了同一个文件,且都未
git add - 然后你回到主仓库根目录(即最初
git init的那个目录)运行git status
此时 Git 会尝试合并各 worktree 的 index 状态,发现冲突就报 Unmerged paths。这不是 bug,是设计行为。解决方式只有两种:
— 进入对应 worktree 先 git add 或 git restore 掉未提交修改
— 或者干脆别在主目录跑 git status,每个 worktree 自己管自己的状态更安全
删 worktree 为什么不能直接 rm -rf
手动删除目录只清空了文件,但 Git 仍在 .git/worktrees/ 下保留元数据记录(比如 HEAD 指向、是否 locked、lock reason 等)。后果很实际:
-
git worktree list仍显示已删路径,状态为prunable - 下次想用相同路径
git worktree add会失败,提示 “working tree … is not empty” - 如果该 worktree 曾被
git worktree lock --reason="on CI"锁定,残留记录还会阻止git worktree prune自动清理
正确流程必须三步走:
— 进入该 worktree 目录,确认无未推送 commit(git log origin/main..HEAD)
— 退出该目录(不能在它内部执行 remove)
— 在任意其他路径运行 git worktree remove ../fix-login
worktree 和 bare repo 能不能混用
不能。bare repo 本身就没有工作区概念,git worktree 命令在 bare repo 中直接报错:fatal: this operation must be run in a work tree。所有 worktree 都必须挂载在 non-bare repo 下。如果你看到别人把 worktree 挂到 NFS 或移动硬盘上,那前提一定是主 repo 本身在本地磁盘且是 non-bare 类型——否则连 git worktree list 都执行不了。


















