Git Worktree 可视化理解指南

一句话理解

一个 Git 仓库,同时在多个目录里检出不同分支,共享同一份 .git 数据库。

无需 clone 多份仓库,就能并行工作在多个分支上。


先搞清楚两个最基础的问题

💡 Q1:这几个文件夹是独立的吗?

是的,它们就是磁盘上 3 个完全独立的文件夹,跟普通文件夹一模一样。

Q2:它们彼此有什么关联?

共享一份隐藏的"历史档案库"(.git),但你肉眼看不到这层关联。


用真实文件演示:一步一步看

假设有一个项目 myapp,就两个文件:README.mdmain.c

第 1 步:原始状态,只有 1 个文件夹

plaintext 复制代码
/home/mi/myapp/          ← 唯一的文件夹(主 worktree)
├── .git/                ← 隐藏文件夹,存所有历史
├── README.md            ← 内容:"main 分支的 README"
└── main.c               ← 内容:printf("main");

此时 git branch 能看到 mainfeature-ahotfix 3 个分支。但文件夹只有一个 ,显示的是当前检出的 main 分支内容。


第 2 步:执行 git worktree add 命令

bash 复制代码
cd /home/mi/myapp
git worktree add ../myapp-feature-a feature-a
git worktree add ../myapp-hotfix    hotfix

执行完后,磁盘上凭空多出两个文件夹

plaintext 复制代码
/home/mi/
├── myapp/                     ← 原来就有的(主 worktree)
│   ├── .git/                  ← 完整的 .git 目录(真正的历史库)
│   ├── README.md              ← "main 分支的 README"
│   └── main.c                 ← printf("main");
│
├── myapp-feature-a/           ← 新出现!
│   ├── .git                   ← 注意:这是一个"文件",不是文件夹!
│   ├── README.md              ← "feature-a 分支的 README"
│   └── main.c                 ← printf("feature");
│
└── myapp-hotfix/              ← 新出现!
    ├── .git                   ← 同样是文件
    ├── README.md              ← "hotfix 分支的 README"
    └── main.c                 ← printf("hotfix");

三个文件夹完全独立,你可以:

  • 用 VSCode 同时开 3 个窗口,每个窗口打开一个文件夹
  • myapp-feature-a/main.c 里改代码,另外两个文件夹纹丝不动
  • 在三个文件夹里分别跑 makenpm start,互不影响

关联在哪?关键在那个"指针文件"

cat 看一下附加 worktree 里的 .git

bash 复制代码
$ cat /home/mi/myapp-feature-a/.git
gitdir: /home/mi/myapp/.git/worktrees/myapp-feature-a

翻译成人话:

"我这个文件夹不存历史。历史都存在主仓库的 .git/ 里。那边才是真老大。"

所以虽然磁盘上看起来是 3 个独立文件夹,但两个附加 worktree 都通过这个小指针挂在 主仓库的 .git/ 上。
/home/mi/myapp-hotfix/
/home/mi/myapp-feature-a/
/home/mi/myapp/ (主 worktree)
指向
指向
.git/

真·历史库

objects / refs / HEAD ...
README.md / main.c

(main 分支内容)
.git 指针文件

gitdir: .../worktrees/feature-a
README.md / main.c

(feature-a 分支内容)
.git 指针文件

gitdir: .../worktrees/hotfix
README.md / main.c

(hotfix 分支内容)

橘黄色 = 真仓库,存着所有 commit 历史。淡蓝色 = 空壳,只有代码文件和一个指向主仓库的小指针。


生活化类比:图书馆的阅览室

把 Git 仓库想象成一座图书馆

概念 图书馆里对应什么
.git 目录 📚 总书库(所有书的所有版本都存在这里)
worktree 📖 阅览室,从书库里调出某一版本的书到桌上看/改
git worktree add 🏗️ 新开一间阅览室,再调一份不同版本的书出来
  • 3 间阅览室(myapp/myapp-feature-a/myapp-hotfix/物理上是 3 个独立房间,互不干扰
  • 但它们共用同一个书库 ,你在任一阅览室把涂改稿"归档"(git commit),书库里立刻多一本新版本,其他阅览室也能看到

自测三道题

读完上面内容,试着回答:

Q1 :在 myapp-feature-a/main.c 改了代码但没 commit,myapp/main.c 会变吗?

不会,三个文件夹的工作区完全独立。

Q2 :在 myapp-feature-a/git commit 后,到 myapp/ 执行 git log feature-a,能看到这个 commit 吗?

,commit 进了共享的 .git 书库,所有 worktree 都能看到。

Q3 :把 /home/mi/myapp/(主 worktree)整个删掉,另外两个还能用吗?

不能 ,它们的 .git 只是指针,指向的真书库没了就全废了。


核心架构:共享 .git,独立工作区

.git 对象库

objects / refs / packed-refs

全局唯一一份
worktree #1(主)

HEAD → main

独立 index / 工作区
worktree #2

HEAD → feature-a

独立 index / 工作区
worktree #3

HEAD → hotfix

独立 index / 工作区

关键点

  • .git 只有一份 → 省磁盘、省带宽
  • 每个 worktree 有自己的 HEADindex → 互不干扰
  • 一处 git fetch,所有 worktree 都能看到新分支

典型场景:紧急修 bug 不打断手头工作

远端仓库 hotfix 工作区(新建) feature 工作区 开发者 远端仓库 hotfix 工作区(新建) feature 工作区 开发者 正在写 feature,代码未完成 无需 stash,无需切分支 上下文完全保留, 改到一半的代码还在 git worktree add ../myapp-hotfix hotfix 定位 bug → 修复 → git commit git push 回到 feature 工作区继续编码

不用 git stash,不用切分支,不用 clone 第二份仓库。


对比:git clone 两份 vs git worktree

方案 B:git worktree
.git

100GB(共享一份)
worktree 1
worktree 2
✅ 磁盘不翻倍

✅ fetch 一次全同步

✅ 分支实时可见
方案 A:git clone 两份
.git #1

100GB
.git #2

100GB
❌ 磁盘翻倍

❌ fetch 两次

❌ 分支状态不同步

仓库越大,优势越明显(想象一下 100GB 的 Chromium 仓库)。


该不该用 worktree?决策图

否,只是偶尔切分支







需要在多分支间工作?
会并行推进

2 个以上任务?
git switch / git stash

就够了
仓库很大

或编译很慢?
✅ 强烈推荐

git worktree
需要并行跑

测试 / CI?
习惯多窗口

并行编辑?


常用命令速查

操作 命令
基于已有分支开 worktree git worktree add ../repo-feat feature-a
开 worktree 并新建分支 git worktree add -b new-branch ../repo-new main
列出所有 worktree git worktree list
移除 worktree(先删目录) git worktree remove ../repo-feat
清理无效元数据 git worktree prune
锁定 worktree(防误删) git worktree lock ../repo-feat

典型用途汇总

🚀

  1. 并行开发 --- 手上的 feature 没写完,随时开 worktree 修 hotfix
  2. 长编译场景 --- 主目录编译中,另开 worktree 写下一个任务(Vela/NuttX 编译慢场景非常实用)
  3. Code Review --- 拉同事分支到独立目录看代码,不污染自己工作区
  4. 版本对比 --- 同时检出 old/new,并排 diff 或对比测试
  5. CI / 脚本任务 --- 自动化任务在独立 worktree 跑,不干扰开发者

注意事项(踩坑清单)

⚠️

  • 🚫 同一分支不能被两个 worktree 同时检出 --- 会报错 already checked out
  • 🧹 删 worktree 目录后必须 git worktree prune --- 否则 .git/worktrees/ 残留元数据
  • 🔒 HEAD / index / reflog 每个 worktree 独立 --- 但对象库共享
  • 📦 git stash 是每个 worktree 独立的 --- 不能跨 worktree 访问 stash

在 Vela/NuttX 项目里

p65-trunk 这类 Google repo 管理的多仓库项目,原生 git worktree 只管单仓库。要一次性给所有子仓开 worktree,用项目里的 repoworktree(rwt) 工具更合适 ------ 它封装了对整个 repo manifest 下所有仓库批量开 worktree 的逻辑,能为每个 feature 开一个完整的多仓隔离工作空间。

相关推荐
透明的玻璃杯2 小时前
git应用
git
炸炸鱼.4 小时前
Git+Jenkins实战(一):从零搭建自动化发布与回滚系统(附完整代码)
git·jenkins
言6666 小时前
要忽略前端依赖包node_modules的文件在目录下 git暂存区消失
git
胡小禾7 小时前
Git Worktree
git
程序员小羊!7 小时前
18 GIt
git
怣疯knight7 小时前
Git 本地分支关联远程分支 常用命令汇总
git
ANNENBERG8 小时前
git分支开发管理
git
坤坤藤椒牛肉面8 小时前
GIT的使用
git
w3296362718 小时前
使用 OpenCode 在 Windows 上加速安装 Playwright 的完整指南
windows·git
我家媳妇儿萌哒哒1 天前
git:无法推送refs到远端。您可以试着运行“拉取”功能,整合您的更改。
git