Git Worktree 使用学习

Git Worktree 使用案例说明

参考文档:git-worktree 官方文档(中文)


一、什么是 Worktree?

Git 默认情况下,一个仓库只有一个工作目录(Working Directory)。git worktree 允许你为同一个仓库关联多个工作目录,每个目录可以独立检出不同的分支,同时共享底层的 .git/objects 对象库,不会重复占用磁盘空间

Git 将工作树分为两类:

  • 主工作树(Main Worktree) :通过 git initgit clone 创建的原始目录。
  • 链接工作树(Linked Worktree) :通过 git worktree add 创建的额外工作目录。

关键约束:同一个分支在同一时刻只能在一个 worktree 中被检出,不能两个 worktree 同时指向同一分支。


二、核心命令速览

命令 说明
git worktree add <路径> [分支] 创建新的链接工作树
git worktree list 列出所有工作树
git worktree remove <路径> 删除链接工作树
git worktree move <源> <目标> 移动工作树到新路径
git worktree lock <路径> 锁定工作树(防止被 prune 清理)
git worktree unlock <路径> 解锁工作树
git worktree prune 清理失效的工作树元数据
git worktree repair 修复工作树关联关系

三、使用案例

案例一:紧急线上 Bug 修复(最典型场景)

背景 :你正在 feature/user-profile 分支上开发新功能,代码写到一半,突然收到告警------线上 main 分支有严重 Bug 需要立即修复。

传统做法的痛点

  • git stash 暂存当前改动,切换到 main 分支修复,再切回来恢复现场,容易出错且打断思路。

使用 Worktree 的做法

第一步:创建新工作树

bash 复制代码
# 在终端执行,基于 main 分支在旁边创建一个新的工作目录
# 执行完成后 ../hotfix-workspace 里已有 main 分支的完整工作文件
git worktree add ../hotfix-workspace main

第二步:在 IDE 中打开新工作树目录

bash 复制代码
# 终端进入新目录,并用 IDE 打开
cd ../hotfix-workspace
code .      # VS Code:在新窗口打开 hotfix-workspace
# idea .   # IntelliJ IDEA
# cursor . # Cursor

此时你有两个 IDE 窗口同时打开:

  • 窗口 A:my-project/,显示 feature/user-profile 分支,你写了一半的代码原封不动
  • 窗口 B:hotfix-workspace/,显示 main 分支的干净代码,在这里做修复

第三步:在窗口 B 中完成 hotfix

bash 复制代码
# 在 hotfix-workspace 目录的终端中执行
git checkout -b hotfix/critical-bug

# 在 IDE 窗口 B 中修改代码,完成后提交
git add .
git commit -m "fix: 修复线上支付金额计算错误"
git push origin hotfix/critical-bug

第四步:回到原来的工作

复制代码
# 直接切回 IDE 窗口 A,my-project/ 里的一切完好如初
# 无需任何 git 操作,继续开发 feature/user-profile

第五步:清理工作树

bash 复制代码
# 在任意目录的终端执行(hotfix-workspace 已无未提交改动)
git worktree remove ../hotfix-workspace
# hotfix-workspace 目录被删除,IDE 窗口 B 自动失效,关掉即可

优势:原分支的工作状态完全保留,无需 stash,两个 IDE 窗口可以同时打开并行工作,互不干扰。


案例二:多功能并行开发

背景 :你需要同时推进 feature/paymentfeature/notification 两个功能,它们互相独立,希望能并行开发、随时切换。

为什么不能直接在两个分支之间来回切换?

表面上看,git checkout feature/paymentgit checkout feature/notification 来回切换似乎可以解决问题,但实际开发中会遇到以下麻烦:

第一,切换分支前必须处理未提交的改动feature/payment 上改了一半的代码还没到提交的程度,这时要切到 feature/notification,Git 会直接拒绝,必须先 git stash 把改动压栈暂存,切换完再 git stash pop 恢复。两个功能来回切换,stash 栈越来越乱,一不小心就会 pop 错或产生冲突。

第二,切换分支会重置整个工作目录的文件。Git checkout 会把所有文件替换成目标分支的版本,IDE 感知到文件变化后会重新索引、重新编译,打开的标签页、调试断点、运行配置全部丢失,每次切换都要重新找回上下文,开发节奏被严重打断。

第三,无法真正并行 。同一个工作目录同一时刻只能对应一个分支,feature/payment 的本地服务和 feature/notification 的本地服务不能同时跑起来做对比。

使用 Worktree 的做法:为每个功能创建独立的工作目录,两个 IDE 窗口同时打开,各自的文件、进程、调试状态完全隔离,随时切换只需切换窗口。

bash 复制代码
# 主工作树在 main 分支
# 为两个 feature 分别创建工作树,各自有一份独立的工作文件
git worktree add ../work-payment feature/payment
git worktree add ../work-notification feature/notification

# 查看当前所有工作树状态
git worktree list
# 输出示例:
# /Users/dev/my-project          abc1234 [main]
# /Users/dev/work-payment        def5678 [feature/payment]
# /Users/dev/work-notification   ghi9012 [feature/notification]

# 在不同目录独立开发,互不干扰
cd ../work-payment
# ... 开发支付功能 ...

cd ../work-notification
# ... 开发通知功能 ...

# 开发完成后逐一清理
git worktree remove ../work-payment
git worktree remove ../work-notification

案例三:Code Review 时快速验证

背景 :同事提了一个 PR,分支名为 feature/new-search,你需要在本地跑起来验证效果,但不想污染自己当前的工作目录。

bash 复制代码
# 先拉取远程分支
git fetch origin feature/new-search

# 创建一个临时工作树用于 Review
git worktree add /tmp/review-new-search origin/feature/new-search

cd /tmp/review-new-search
# 安装依赖、启动服务、验证功能
npm install && npm run dev

# Review 完成,删除临时工作树
git worktree remove /tmp/review-new-search

案例四:多版本并行维护

背景 :项目同时维护 v1.xv2.x 两个大版本,需要分别修复 Bug 并发布补丁。

bash 复制代码
# 为每个维护版本创建独立工作树
git worktree add ../project-v1 release/v1
git worktree add ../project-v2 release/v2

# 在 v1 目录修复 v1 的 Bug
cd ../project-v1
git checkout -b hotfix/v1-security-patch
# ... 修复 ...
git commit -m "fix: v1 安全漏洞修复"

# 在 v2 目录修复 v2 的 Bug
cd ../project-v2
git checkout -b hotfix/v2-security-patch
# ... 修复 ...
git commit -m "fix: v2 安全漏洞修复"

案例五:创建不关联任何分支的临时工作树

背景 :需要一个干净的工作区做实验,不想关联任何现有分支(使用 --detach 或孤立分支)。

bash 复制代码
# 创建一个游离 HEAD 状态的工作树(基于某个 commit)
git worktree add --detach ../experiment-workspace HEAD

# 或者创建一个全新的孤立分支工作树
git worktree add --orphan -b experiment/sandbox ../sandbox-workspace

cd ../sandbox-workspace
# 随意实验,不影响任何分支

案例六:锁定工作树(防止误清理)

背景 :某个链接工作树挂载在可移动磁盘或网络路径上,担心 git worktree prune 因路径暂时不可达而误删元数据。

bash 复制代码
# 锁定工作树,并附上说明原因
git worktree lock ../work-on-external-disk --reason "挂载在移动硬盘上,暂时不可用"

# 查看锁定状态
git worktree list --porcelain
# 输出中会显示 locked 字段

# 磁盘重新挂载后,解锁
git worktree unlock ../work-on-external-disk

案例七:清理失效的工作树

背景 :某个链接工作树的目录被手动删除(而不是通过 git worktree remove),导致 .git/worktrees/ 下残留了无效的元数据。

bash 复制代码
# 查看当前工作树,发现有 prunable 状态的条目
git worktree list

# 预览将被清理的内容(不实际执行)
git worktree prune --dry-run

# 执行清理
git worktree prune

# 如果工作树目录被移动了,可以修复关联关系
git worktree repair ../new-location-of-worktree

四、与 git stash 的对比

对比维度 git stash git worktree
切换成本 需要 stash → checkout → pop,步骤多 直接切换目录,零成本
并行工作 不支持,同一时刻只能在一个分支 支持,多目录同时工作
编辑器支持 只能打开一个工作目录 可同时在多个 IDE 窗口打开
磁盘占用 无额外占用 共享对象库,仅多一份工作文件
适用场景 短暂的临时切换 长期并行、多版本维护

五、注意事项

同一分支不能被两个 worktree 同时检出 。如果尝试这样做,Git 会报错:fatal: 'xxx' is already checked out。解决方法是先在另一个 worktree 中切换到其他分支,再在当前 worktree 检出目标分支。

删除工作树要用命令而非手动删除目录 。直接删除目录会导致 .git/worktrees/ 下残留元数据,需要后续用 git worktree prune 清理。

主工作树不能被 removegit worktree remove 只能删除链接工作树,主工作树是仓库本身,无法通过此命令删除。

工作树中有未提交改动时无法直接删除 。需要加 --force 参数强制删除,或先提交/丢弃改动再删除。

bash 复制代码
# 强制删除含有未提交改动的工作树
git worktree remove --force ../dirty-worktree

cd 切换目录不等于切换编辑器视图 。在终端执行 cd ../hotfix-workspace 后,只有终端的工作目录发生了变化,VS Code、IDEA 等编辑器窗口仍然显示原目录的文件。需要在编辑器中手动打开新的工作树目录(code . / idea .),或者提前为每个工作树开一个独立的编辑器窗口,才能真正在对应分支的代码上进行编辑。


六、推荐目录结构

建议将所有链接工作树统一放在主仓库的同级目录,或使用专门的 .trees/ 子目录(需加入 .gitignore):

复制代码
# 方式一:同级目录(推荐,路径清晰)
~/projects/
  my-project/          ← 主工作树 (main)
  my-project-hotfix/   ← 链接工作树 (hotfix/xxx)
  my-project-v2/       ← 链接工作树 (release/v2)

# 方式二:子目录(集中管理)
~/projects/my-project/
  .trees/
    feature-payment/   ← 链接工作树
    feature-notify/    ← 链接工作树

使用子目录方式时,记得在 .gitignore 中添加 .trees/,避免被 Git 追踪。

相关推荐
Z文的博客1 小时前
嵌入式LINUX QT 开发 .gitignore 文件编写指南
linux·git·qt·elasticsearch·嵌入式
YouCanYouUp.1 小时前
个人成长与目标执行手册 V1.0
学习
IT空门:门主1 小时前
Python 数据类型学习笔记
python·学习
学习论之费曼学习法1 小时前
AI 入门 30 天挑战 - Day 20 费曼学习法版 - 语音识别基础
人工智能·学习·语音识别
星幻元宇VR1 小时前
VR交通安全行走平台助力文明交通建设
科技·学习·安全·vr·虚拟现实
前端双越老师2 小时前
3 个命令 7 个步骤,学会 git worktree 并行开发
git·ai编程·全栈
red_redemption2 小时前
自由学习记录(174)
学习
sjsjsbbsbsn2 小时前
RAG核心学习总结:文本分块
人工智能·学习·知识图谱
li星野2 小时前
链表通关八题:从反转链表到两数相加,手撕LeetCode高频题
数据结构·学习·leetcode·链表