Git Worktree:同时处理多个分支的正确姿势

遇到过这种情况吗?

正写着代码,突然产品经理跑过来说线上出bug了,得马上修。你看看自己的工作区:改了一半的文件、新加的测试代码、还有几个临时文件......这时候你会怎么办?

以前我都是 git stash,改完bug再 stash pop 回来。但有时候 stash 多了就乱了,pop 的时候还可能冲突。后来发现 git worktree 这个功能,简直完美解决了这个问题。

Worktree 是什么?

说白了就是让你在一个 Git 仓库里同时 checkout 多个分支到不同的文件夹。比如:

bash 复制代码
project/                 # 主目录,开发新功能
project-hotfix/         # 修bug用
project-review/         # 看别人代码用

这三个目录用的是同一个 Git 仓库,提交、分支这些都是共享的,但每个目录可以切到不同分支,互不干扰。

想了解更多细节?可以看看 Git 官方文档

常用命令详解

1. 添加工作区 (add)

基本语法:

css 复制代码
git worktree add [选项] <路径> [<提交号>]

常见用法:

csharp 复制代码
# 最简单:自动创建同名分支
git worktree add ../hotfix
# 会在 ../hotfix 目录创建名为 hotfix 的新分支

# 基于现有分支创建工作区
git worktree add ../feature-test feature-branch
# checkout 已存在的 feature-branch 分支

# 创建新分支
git worktree add -b new-feature ../new-feature
# 基于当前 HEAD 创建新分支

# 基于指定提交创建新分支
git worktree add -b bugfix-v1 ../bugfix v1.0.0
# 从 v1.0.0 标签创建 bugfix-v1 分支

# 创建分离 HEAD(不关联任何分支)
git worktree add -d ../temp-check
# 适合临时查看代码,不打算提交

常用参数说明:

  • -b <新分支名>:创建新分支并 checkout
  • -B <分支名>:强制创建分支,如果已存在则重置它
  • -d--detach:创建分离 HEAD 状态的工作区
  • -f--force:强制操作,即使分支已在其他工作区被 checkout
  • --lock:创建后立即锁定工作区,防止被删除或移动
  • --orphan:创建孤儿分支(空历史的新分支)

智能分支追踪: 如果你指定的分支在本地不存在,但远程有同名分支,Git 会自动帮你创建并设置追踪:

bash 复制代码
git worktree add ../feature-auth feature-auth
# 如果本地没有 feature-auth,但 origin/feature-auth 存在
# 会自动创建本地分支并追踪远程分支

2. 查看工作区列表 (list)

基本语法:

css 复制代码
git worktree list [选项]

示例:

shell 复制代码
# 基本列表
git worktree list
# 输出:
# /path/to/project        abc1234 [main]
# /path/to/project-hotfix def5678 [hotfix-bug]
# /path/to/temp          789abc0 (detached HEAD)

# 详细信息(显示锁定原因等)
git worktree list --verbose
# 输出:
# /path/to/project        abc1234 [main]
# /path/to/locked-work    def5678 [feature-a]
#     locked: 在移动硬盘上
# /path/to/prunable      789abc0 (detached HEAD)
#     prunable: gitdir 文件指向不存在的位置

# 机器可读格式(适合脚本解析)
git worktree list --porcelain

常用参数:

  • -v--verbose:显示详细信息,包括锁定原因
  • --porcelain:以固定格式输出,方便脚本解析
  • -z:配合 --porcelain 使用,用 NUL 字符分隔(处理路径中包含换行的情况)

3. 删除工作区 (remove)

基本语法:

arduino 复制代码
git worktree remove [选项] <工作区>

示例:

bash 复制代码
# 删除干净的工作区
git worktree remove ../hotfix

# 强制删除(即使有未提交的更改)
git worktree remove -f ../hotfix

# 删除锁定的工作区(需要两次 --force)
git worktree remove --force --force ../locked-work

参数说明:

  • -f--force:强制删除脏工作区(有未提交的修改)
  • --force --force:强制删除锁定的工作区

4. 移动工作区 (move)

基本语法:

xml 复制代码
git worktree move <工作区> <新路径>

示例:

bash 复制代码
# 移动工作区到新位置
git worktree move ../hotfix ../urgent-fix

# 移动锁定的工作区(需要两次 --force)
git worktree move --force --force ../locked-work ../new-location

**注意:**主工作区和包含子模块的工作区不能移动。

5. 锁定/解锁工作区 (lock/unlock)

基本语法:

xml 复制代码
git worktree lock [选项] <工作区>
git worktree unlock <工作区>

示例:

bash 复制代码
# 锁定工作区并说明原因
git worktree lock ../portable-work --reason "在移动硬盘上"

# 解锁工作区
git worktree unlock ../portable-work

使用场景: 工作区在移动硬盘、U盘或网络盘上,不希望被自动清理时使用。

6. 修复工作区 (repair)

基本语法:

css 复制代码
git worktree repair [<路径>...]

示例:

bash 复制代码
# 在主工作区修复所有链接
git worktree repair

# 修复特定工作区(如果手动移动了目录)
git worktree repair /new/path/to/moved-worktree

# 修复多个工作区
git worktree repair ../work1 ../work2 ../work3

使用场景:

  • 手动移动了工作区目录
  • 手动移动了主仓库
  • Git 连接损坏需要重建

7. 清理过期记录 (prune)

基本语法:

css 复制代码
git worktree prune [选项]

示例:

bash 复制代码
# 清理已删除工作区的记录
git worktree prune

# 预览会删除什么(不实际删除)
git worktree prune -n

# 显示详细清理过程
git worktree prune -v

# 清理超过指定时间未使用的工作区
git worktree prune --expire 7.days.ago

参数说明:

  • -n--dry-run:只显示会删除什么,不实际删除
  • -v--verbose:显示详细信息
  • --expire <时间>:只清理超过指定时间的记录

使用场景: 如果你直接用 rm -rf 删除了工作区目录(不推荐),用这个命令清理 Git 中的残留记录。

真实使用场景

场景一:紧急修bug

bash 复制代码
# 赶紧创建个新目录改bug
git worktree add ../hotfix main

cd ../hotfix
# 改代码,提交
git commit -am "修复登录问题"
git push

# 回到原来的目录继续写代码
cd -

# bug修完了,删掉这个临时目录
git worktree remove ../hotfix

整个过程原来的工作区一点没动,改了一半的代码还在那儿。

场景二:Code Review

要看同事的代码,但不想影响自己正在写的:

bash 复制代码
git worktree add ../review-pr feature/user-login
cd ../review-pr
# 慢慢看代码,跑跑测试

看完直接删掉就行,不用来回切分支。

场景三:同时开发多个功能

css 复制代码
git worktree add ../feature-a -b feature-a
git worktree add ../feature-b -b feature-b

写着写着 feature-a 卡住了?直接去 feature-b 目录写别的,不用切来切去。

场景四:测试不同版本

bash 复制代码
# 测试当前版本
git worktree add -d ../test-current

# 测试旧版本
git worktree add -d ../test-v1 v1.0.0

# 测试完删掉
git worktree remove ../test-current
git worktree remove ../test-v1

一些坑和注意事项

同一个分支不能在多个工作区同时 checkout

会报错。想想也合理,不然容易乱。非要这么干的话加 --force,但我从没这么用过。

直接删文件夹不行

别直接 rm -rf 删工作区目录,用 git worktree remove。否则 Git 里还留着记录,虽然可以用 git worktree prune 清理,但还是麻烦。

子模块支持不太好

文档里明说了,有子模块的项目最好别用 worktree。我试过几次确实有点问题。

移动目录后要修复

如果手动把工作区目录挪了地方,记得运行:

复制代码
git worktree repair

主工作区不能删除

git worktree remove 只能删除链接工作区,主工作区(最初 clone 或 init 的那个)删不了。

小技巧

目录名起得有意义点

别都叫 temp1temp2,过两天就忘了哪个是哪个。我一般这样:

sql 复制代码
git worktree add ../fix-issue-123 -b fix-issue-123
git worktree add ../feature-user-auth -b feature-user-auth

定期清理

偶尔跑一下 git worktree list,看看有没有不用的工作区。该删的删掉,保持干净。

用相对路径还是绝对路径?

看个人习惯。我一般用相对路径 ../xxx,这样整个项目目录移动也不影响。如果需要绝对路径,可以在配置中设置:

arduino 复制代码
git config worktree.useRelativePaths false

创建时就锁定

如果知道工作区在移动设备上,创建时直接锁定:

csharp 复制代码
git worktree add --lock ../portable-work --reason "在U盘上"

什么时候用 Worktree?

适合用:

  • 需要紧急切换任务
  • 同时开发多个功能
  • Code Review 不想影响当前工作
  • 想在不同分支间对比代码
  • 测试不同版本的代码

不适合用:

  • 项目有子模块
  • 只是临时看看代码(直接 git show 或者 GitHub 上看就行)
  • 磁盘空间紧张(每个工作区都要占空间)

总结

Worktree 这功能其实很早就有了,但知道的人不多。用习惯之后真的回不去了,尤其是经常被打断改 bug 的时候。

不过也别滥用,大部分情况下一个工作区够用了。真需要的时候,Worktree 能帮你省不少事儿。

想深入了解所有选项和高级用法,建议看看 Git 官方文档的 Worktree 章节,里面讲得很详细。

快速参考

csharp 复制代码
# 创建工作区
git worktree add <路径>                    # 自动创建同名分支
git worktree add <路径> <分支>              # 基于现有分支
git worktree add -b <新分支> <路径>         # 创建新分支
git worktree add -d <路径>                 # 分离HEAD

# 查看和管理
git worktree list                         # 查看所有工作区
git worktree list -v                      # 详细信息
git worktree remove <路径>                 # 删除工作区
git worktree prune                        # 清理记录

# 锁定和修复
git worktree lock <路径>                   # 锁定
git worktree unlock <路径>                 # 解锁
git worktree repair                       # 修复连接
相关推荐
-拟墨画扇-4 小时前
Git | 配置别名操作
git·gitee·github·gitcode
-拟墨画扇-5 小时前
Git | 多人协助策略
git·gitee·github·gitcode
BestOrNothing_20155 小时前
Git 原理彻底讲透:工作区 / 暂存区 / 本地仓库 / origin 一次理清(VSCode 可视化 + 实战避坑)
git·分支开发·fetch / merge·add / commit·pull / push·工作区/暂存区/本地仓库
Huazzi.5 小时前
使用Scoop安装Git
git·elasticsearch·gitee·ssh·github·scoop
马达加斯加D5 小时前
git --- reset 删除提交
git
10000hours6 小时前
【Git】git常用命令
git
KevinRay_6 小时前
Github如何上传项目(超详细小白教程)
git·gitee·开源·github·vim
乖乖是干饭王14 小时前
GIT仓库本地部署
git
-拟墨画扇-21 小时前
Git | 分支管理操作
git·gitee·github·gitcode