Git:临时看另一个分支时,`worktree` 比来回切分支省心

47 次浏览6 条回复

有时候手上这个分支改到一半,又想去另一个分支看几行代码。直接 checkout 很容易被未提交改动拦住,这种场景可以试试 git worktree。

环境:Git 2.5+。找个空目录跑:

mkdir worktree-demo && cd worktree-demo
git init
printf 'main\n' > app.txt
git add app.txt && git commit -m init

git switch -c feature
printf 'feature\n' > app.txt
git commit -am feature

git switch main
git worktree add ../worktree-feature feature
cat ../worktree-feature/app.txt

最后会在旁边多出一个 worktree-feature 目录,里面停在 feature 分支;原来的目录还留在 main。

看完可以清掉:

git worktree remove ../worktree-feature

我觉得它最适合那种“改到一半但突然要查另一个分支”的小场景,不用 stash 来 stash 去。

补一个小点:如果 worktree 用多了,git worktree list 可以先看一下都挂了哪些目录。

有时候目录被手动删掉了,Git 这边还留着记录,可以再跑:

git worktree prune

不然时间久了会有点乱。

还有个容易踩的小坑:同一个分支一般不能同时挂在两个 worktree 里。

比如当前目录已经在 main,再 git worktree add ../x main 多半会被拦住。只是想临时看一眼的话,可以用 detached:

git worktree add --detach ../peek main

或者直接从那个提交拉个新分支出来。这个限制其实也挺合理,避免两个目录同时改同一根分支。

这个还有个小技巧:如果只是想基于远端分支开一个临时目录,可以顺手让它新建本地分支,避免直接动到原分支。

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

看代码、做个小补丁都挺干净。最后删目录前记得先把改动提交或丢掉,不然 worktree remove 会拦一下。

还可以顺手记一下 git worktree lock。

如果 worktree 放在移动硬盘、临时挂载目录这类位置,偶尔不在线,直接 prune 可能会误清记录:

git worktree lock ../worktree-feature
git worktree unlock ../worktree-feature

不常用,但遇到“目录不是一直挂着”的场景挺有用。

再补一个适合多人项目的用法:review 别人的 PR 时,可以给它单独拉一个 worktree,不影响当前手头分支。

git fetch origin pull/123/head:pr-123
git worktree add ../review-pr-123 pr-123

看完再 git worktree remove ../review-pr-123。这样本地正在改的东西不用先收拾,脑子也少切换一点。

还有一个不太起眼但挺实用的命令:worktree 目录想换位置时,不用手动搬完再修 Git 记录,可以用:

git worktree move ../worktree-feature ../tmp/worktree-feature

前提是目标目录不存在,而且 worktree 里最好先别留未收拾的改动。比自己 mv 以后再排查路径问题省点心。