用 git worktree 并行开发多分支:命令、测试与共享 .git 注意事项
用 git worktree 并行开发多分支
问题场景
同一个仓库里,主分支要修紧急缺陷,功能分支要补测试,另一个分支还要复现用户问题。频繁 git switch 和 git stash 会带来几个麻烦:工作区容易变脏,暂存内容可能混淆,测试进程还会被下一次切换打断。git worktree 的思路是:同一个仓库可以关联多个工作目录,每个目录检出不同分支,但共享同一个 .git 对象库和引用。这样每个目录有独立的工作区和索引,能并行改代码、跑测试,减少切换和 stash。
最小可运行示例
在一个空目录中执行以下命令。示例用 test.sh 打印当前目录,实际使用时换成项目测试命令。
mkdir demo-repo && cd demo-repo
git init
git config user.email demo@example.com
git config user.name demo
cat > test.sh <<'EOF'
#!/bin/sh
pwd
EOF
chmod +x test.sh
git add test.sh
git commit -m 'init'
git branch feature/a
git branch feature/b
git worktree add ../demo-feature-a feature/a
git worktree add ../demo-feature-b feature/b
git worktree list
(cd ../demo-feature-a && ./test.sh) &
(cd ../demo-feature-b && ./test.sh) &
wait
git worktree remove ../demo-feature-a
git worktree remove ../demo-feature-b
运行方法:逐段执行即可。git worktree list 会列出主工作目录和两个新目录;两个 ./test.sh 会并行运行,输出各自的绝对路径;wait 等待两个后台任务结束。删除 worktree 后,分支 feature/a、feature/b 仍然保留,需要时再删除分支。
常用命令
- 检出已有分支:
git worktree add ../repo-feature-a feature/a - 从当前提交新建分支并检出:
git worktree add -b feature/c ../repo-feature-c HEAD - 查看工作树:
git worktree list,脚本中可用git worktree list --porcelain - 删除工作树:
git worktree remove ../repo-feature-a,工作区有未提交修改时默认拒绝,--force会丢弃修改 - 清理失效元数据:手动删除目录后执行
git worktree prune - 防止误删:
git worktree lock ../repo-feature-a
共享 .git 的注意事项
- 同一分支不能同时在两个 worktree 中检出。Git 会拒绝重复检出同一分支。如果确实要并行修改同一分支,可先建临时分支,或用
git worktree add --detach ../repo-tmp HEAD进入分离头指针状态,完成后再把提交合并回目标分支。 - 提交和分支引用共享,工作区与索引独立。在一个 worktree 中提交后,其他 worktree 能立即看到新提交和分支变化;但
git add、未提交修改、当前检出内容互不影响。 - 删除 worktree 不等于删除分支。
remove删除的是工作目录和对应的管理信息,分支和已提交对象仍在共享仓库中;未提交修改会随目录删除而丢失,先提交或复制出来。 - stash 是仓库级共享的。不要把
git stash当作多个 worktree 之间的隔离手段;并发 stash/pop 容易混淆。需要隔离时,优先用临时提交或补丁文件。 - 维护类命令最好串行。多个 worktree 同时跑测试时,避免同时在另一个 worktree 执行重写历史、强制清理对象等操作;先协调,减少共享引用和对象库上的竞争。
- hooks 和部分配置共享。
.git/hooks对所有 worktree 生效;若需要每个 worktree 独立配置,可启用extensions.worktreeConfig后使用git config --worktree。普通场景不必展开。 - 子模块要分别初始化。仓库含子模块时,每个 worktree 仍需执行
git submodule update --init获取自己的工作副本。 - 路径不要嵌套在另一个 worktree 内。把新目录放在仓库同级或独立目录,删除和清理更清晰。
边界与限制
worktree 解决的是“同一仓库多分支工作目录”的问题,不是完整沙箱:多个目录仍可能争用同一个测试端口、数据库、缓存目录或构建缓存,需要在测试命令里分配不同端口或临时目录。它也不适合把同一分支同时检出到多处;这种需求应改用临时分支或分离头指针。最后,remove 前确认没有未提交内容,手动删目录后记得 prune,避免 list 中出现失效记录。
小结
用 git worktree add 建目录、list 查看、remove 清理,可以把“切分支再 stash”的串行操作变成多个工作目录的并行开发。关键是记住:共享 .git,但工作区独立;同一分支只检出一处;删除目录先处理未提交修改。
- 点赞
- 收藏
- 关注作者
评论(0)