Git worktree:并行切分支,不用来回 stash

42 次浏览5 条回复

同时处理两个分支时,可以用 git worktree 给每个分支单独的工作目录,省得在同一个目录里反复切换。

环境:Git 2.30+。最小例子:

mkdir worktree-demo && cd worktree-demo
git init -q
git config user.email [email protected]
git config user.name dev
printf 'base\n' > note.txt
git add note.txt && git commit -qm 'init'

git branch feature
git worktree add ../worktree-feature feature

printf 'main change\n' >> note.txt
git worktree list

当前目录还是默认分支,../worktree-feature 则直接停在 feature。两个目录可以分别开编辑器或跑测试。用完执行 git worktree remove ../worktree-feature,主仓库里的提交和分支不会因此被删。

还有个小提醒:worktree remove 默认不会替你处理工作目录里的未提交改动,想保留的话先确认一下;临时 worktree 删掉后,也可以用 git worktree prune 清理失效记录。分支本身还在,之后照常切回或删除即可。

补一个刚开始用时容易撞上的限制:同一个普通分支不能同时被两个 worktree 检出。需要在第二个目录改同一份提交时,可以先建个临时分支:git worktree add -b fix-copy ../fix-copy feature。这样两个目录各自有分支,提交也不会互相卡住。

ZiorLv1#2

补一个刚开始用时容易撞上的限制:同一个普通分支不能同时被两个 worktree 检出。需要在第二个目录改同一份提交时,可以先建个临时分支:git worktree add -b fix-copy ../fix-copy feature。这样两个目录各自有分支,提交也不会互相卡住。

再补一个容易忽略的点:如果 worktree 放在移动盘或网络目录,暂时不可用时可以先 git worktree lock ../worktree-feature --reason "offline",Git 就不会把它当成失效目录清理。目录恢复后再 git worktree unlock。普通本地目录一般用不到这个。

MukiLv1#3

再补一个容易忽略的点:如果 worktree 放在移动盘或网络目录,暂时不可用时可以先 git worktree lock ../worktree-feature --reason "offline",Git 就不会把它当成失效目录清理。目录恢复后再 git worktree unlock。普通本地目录一般用不到这个。

还有个和脚本集成有关的细节:worktree 里的 .git 通常只是指向主仓库的文件,不要把 $PWD/.git 当真实目录拼路径。脚本里用 git rev-parse --show-toplevel 或 git rev-parse --git-common-dir 取路径更稳,清理临时 worktree 时尤其有用。

脚本里批量处理时,git worktree list --porcelain 比普通列表更好解析,会把每个 worktree 的 worktree、HEAD、branch 分字段输出。需要判断某个分支是否已经被别的目录占用时,拿它做机器读取比解析人类可读输出稳。