Git worktree:不打断当前改动,单独处理临时修复

55 次浏览3 条回复

手头分支有未提交改动时,如果突然需要基于主分支处理一个独立修复,git worktree 可以新增工作目录,共用同一仓库对象库,又不必暂存当前现场或重新克隆。

环境:Git 2.39+;Bash 或 zsh;仓库远端名为 origin,主分支为 main

先更新远端引用,再从 origin/main 创建新分支和工作目录:

git fetch origin
git worktree add -b fix/login-timeout ../myapp-login-fix origin/main
git worktree list

原目录仍停留在当前分支;新目录已经检出 fix/login-timeout。可以直接在新目录执行命令,而不必来回 cd

git -C ../myapp-login-fix status
git -C ../myapp-login-fix log -1 --oneline

完成修改、提交并合并后,回到原仓库移除工作目录:

git worktree remove ../myapp-login-fix
git worktree prune

有三个细节值得注意:

  1. 同一个本地分支不能同时检出到两个 worktree;新增目录时使用独立分支名。
  2. 每个 worktree 的工作区和暂存区彼此独立,但提交与引用属于同一仓库,因此一边创建的提交会立即被另一边看到。
  3. git worktree remove 默认会拒绝移除含未提交改动的目录。先确认状态,不要把 --force 当作常规清理方式。

这套流程尤其适合临时修复、代码审查和多版本验证:保留原任务上下文,同时让每个工作目录维持清晰的分支边界。

补充一个适合一次性代码审查的用法:如果只需要查看或验证某个提交,不准备在该目录继续开发,可以用 detached worktree,避免额外创建临时分支。

环境:Git 2.39+;将 <commit> 替换为已存在的提交哈希或远端引用。

git fetch origin
git worktree add --detach ../myapp-review <commit>
git -C ../myapp-review status
# 在该目录运行项目自己的构建或测试命令
git worktree remove ../myapp-review

--detach 下的新提交不会自动归属于分支;如果验证过程中确实需要保留修改,先在该 worktree 中执行 git switch -c review/fix-name 再提交。这样“只读验证”和“继续开发”的意图会更清楚。

再补一个外接盘或临时挂载目录的场景:worktree 路径可能暂时不可访问时,可以先锁定,避免维护命令把它当成失效记录清理。

环境:Git 2.39+;示例中的 /mnt/ssd 已挂载且可写;远端名为 origin

git fetch origin
git worktree add -b perf/bench /mnt/ssd/myapp-perf origin/main
git worktree lock --reason "stored on removable SSD" /mnt/ssd/myapp-perf
git worktree list --porcelain

list --porcelain 会输出 locked 及原因,适合脚本检查。外接盘恢复稳定挂载、准备正常清理时再解锁:

git worktree unlock /mnt/ssd/myapp-perf
git worktree remove /mnt/ssd/myapp-perf
git worktree prune

这里的 lock 保护的是主仓库中的 worktree 管理记录,不会锁住分支,也不会阻止该目录内正常提交。

补充一个目录改名或迁移的细节:正常迁移已登记的 linked worktree 时,优先使用 git worktree move,它会同步更新主仓库里的管理信息。

环境:Git 2.39+;以下命令在主工作目录执行;目标目录的父目录已存在。

mkdir -p ../worktrees
git worktree move ../myapp-login-fix ../worktrees/login-fix
git worktree list --porcelain
git -C ../worktrees/login-fix status

如果目录已经被文件管理器或 mv 手动挪走,list 中可能仍保留旧路径。这时可从主工作目录修复登记信息:

git worktree repair ../worktrees/login-fix
git worktree list --porcelain
git -C ../worktrees/login-fix status

repair 适合补救路径失配,不等于恢复未提交文件;迁移前仍应先检查 git -C <path> status。主工作目录以及包含子模块的 worktree 还有额外限制,计划性迁移前可先运行 git worktree move -h 确认当前 Git 版本支持的情形。