DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

Git 切换分支报 already checked out at,分支被另一个 worktree 占用

Git 切换分支提示 already checked out at 或 already used by worktree at,先确认另一目录是否仍在使用。按继续开发、独立快照、目录移动或已删除,选择释放分支、独立分支、repair 或预览后 prune。

在一个工作目录里切换分支,Git 却指向另一个目录并拒绝操作:

fatal: 'feature-login' is already checked out at '/path/to/other-worktree'

有些版本会显示 is already used by worktree at。这通常表示同一仓库的另一个 worktree 正在使用该分支,未必是锁文件损坏,也不意味着需要删除整个 .git/worktrees。

同一仓库的 worktree 共享分支引用,但分别保留自己的 HEAD、暂存区和工作文件。如果两边同时检出同一分支,一边提交后共享分支指针会前进,另一边的暂存区和文件却不会随之更新。Git 默认拒绝这种重复占用,防止分支指针与另一目录的文件状态脱节。

下面处理同一仓库的 linked worktree。路径均为占位值;分支 feature-login 已存在。示例中的 git switch 需要 Git 2.23 或更新版本,其他 worktree 子命令也应以本机 git worktree -h 提供的能力为准。

先看报错目录是否仍在使用

在当前仓库列出 worktree,再检查报错所指目录:

git worktree list --porcelain
git -C '/path/to/other-worktree' status

列表中的 worktree 是目录,branch refs/heads/feature-login 表示该目录检出了目标分支。locked 和 prunable 是额外状态,不能一概当成垃圾记录。status 则能看出目录内有没有修改,以及是否有尚未结束的操作。

即使列表显示 detached HEAD,也不能立即认定分支已释放:其他 worktree 中尚未完成的 rebase 等操作也可能让分支处于使用状态。先到对应目录读取状态,确认由谁、哪个工具启动了操作,再决定继续还是取消。不要为切换分支而直接删除操作状态文件,或未经核对就中止别人的 rebase。

如果路径位于外置盘、网络共享或尚未挂载的目录,先恢复挂载。暂时访问不到目录,与目录已经永久删除是两回事。

只是要继续修改这个分支

可以直接在已经使用该分支的目录继续工作:

cd '/path/to/other-worktree'
git status

进入目录本身不会执行一次新的 checkout;该目录原本就有自己的分支状态。确认状态和预期一致后,在这里编辑、提交即可,不需要再到另一个 worktree 检出同一个分支。

如果必须在当前目录使用该分支,先确认另一目录没有运行中的任务、未完成的 Git 操作或需要保留的未提交工作。保存必要文件并记下当前提交后,可以在另一目录脱离分支,再在当前目录切换:

git -C '/path/to/other-worktree' switch --detach
git switch feature-login

第一条命令不指定新提交,另一目录会停留在当前提交,但不再跟随 feature-login。这适合明确希望保留那份代码快照的情况;如果那里的服务或工具依赖分支自动前进,就不应贸然改变它。

执行第二条时,当前目录若还有会被覆盖的修改,Git 仍可能拒绝切换。应先保存这些修改,不能加 --discard-changes 把新的保护提示绕过去。对于任何必须保留的未跟踪或忽略文件,也应有独立备份,不能把分支切换当作备份手段。

以后要把分支交还原目录,先在当前目录保存工作并脱离该分支,再在原目录切回。两边不要同时修改共享分支指针。

需要第二份代码,但不需要共用分支

只想查看或运行该分支当前提交时,可以创建 detached worktree。新路径应尚不存在,并位于合适的工作区:

git worktree add --detach '/path/to/review-worktree' feature-login

新目录固定在创建时的提交,不会随另一边的分支提交自动更新。它也不会包含另一 worktree 尚未提交的修改。

如果这份代码接下来也要独立开发,更清楚的方式是创建新分支:

git worktree add -b review-login '/path/to/review-worktree' feature-login

这两条命令是二选一,不要对同一个新路径连续执行。review-login 应是尚不存在的新分支,起点是当前 feature-login 指向的提交。之后两条分支各自前进,需要时再审查并合并变更。

在 detached worktree 中已经产生了想保留的提交,应在离开前为它创建分支:

git -C '/path/to/review-worktree' switch -c saved-review-login

分支名同样需要未被使用。否则离开 detached HEAD 后,新提交可能只剩 reflog 等记录可追查,不能当作已可靠保存的分支成果。

目录确实删掉了,Git 仍保留登记

如果旧 worktree 是被文件管理器直接删除的,Git 可能还保留其管理信息。先确认目录没有被移动、没有等待挂载、也不包含尚未找回的工作,再预览清理范围:

git worktree prune --dry-run --verbose --expire now

--dry-run 只报告拟清理内容;--expire now 让预览包含当前已经过期的缺失目录记录。检查输出中的每一个路径,因为 prune 针对整个仓库的候选记录,不只针对这一次报错里的分支。

只有所有拟清理项都确认属于已经废弃的目录时,才去掉 --dry-run:

git worktree prune --verbose --expire now
git worktree list --porcelain
git switch feature-login

prune 清理的是缺失 worktree 的管理信息,不会把仍在使用的 worktree 正常“退出分支”。清理前若还有任何目录需要恢复,应保留仓库管理数据和相关目录备份,先恢复或修复连接;不要事后指望 prune 能撤销或还原丢失的文件。

如果只是把目录搬到了新位置,应修复连接,而不是清除登记。当前 Git 支持从仍有效的 worktree 指定新路径:

git worktree repair '/path/to/moved-worktree'
git worktree list --porcelain

先确认新位置是原来的工作目录。本机没有 repair 子命令时,保留目录和管理数据,使用支持该命令的 Git 版本处理,避免手工猜测并修改 .git 内部路径。

不再需要的 worktree 用正常移除流程收尾

对仍存在的 linked worktree,先查看状态,保存要保留的提交、文件和本地配置,再正常移除:

git -C '/path/to/review-worktree' status --short
git worktree remove '/path/to/review-worktree'

remove 会删除工作目录,不能只理解为释放分支。它通常只接受干净的 worktree;若存在修改、未跟踪文件、子模块或锁而被拒绝,应按提示确认原因,不直接添加 --force。干净状态也不能替代对忽略文件和本地配置的备份检查。主 worktree 不能用这个命令删除。

最终应确认:git worktree list --porcelain 中各个保留目录对应的分支正确,目标目录的 git status 显示预期分支,原有提交与需要保留的文件仍在。不要用删除整个 .git/worktrees、强制重建同名分支,或 --ignore-other-worktrees 作为常规修复;这些操作会破坏登记或绕过共享分支的保护,不能替代对占用状态的判断。