前言
你有没有遇到过这种情况——
正在 feature-a 分支上写代码写得正起劲,产品经理突然跑过来:”线上 bug!马上修!”
这时候你只有两个选择:
-
git stash存一下,切到main,修完 bug,再切回来,git stash pop恢复现场 -
硬着头皮 commit 一个 “WIP” 提交,切分支,修完再切回来
不管哪种方式,都要打断手头的工作,IDE 里打开的文件全部变了,心态也跟着乱了。
今天要介绍的 git worktree 命令,能彻底解决这个问题——让你在同一个仓库里同时检出多个分支,每个分支都有独立的工作目录,互不干扰。
这篇文章会带你从零上手 worktree,所有命令都在 Windows 上实测可跑。看完跟着练一遍,半小时就能掌握。
一、分支和 Worktree 到底有什么区别?
这是很多人容易混淆的地方,先把概念理清楚。
分支(Branch)是什么?
分支本质上是一个指向某个 commit 的可移动指针。它非常”轻”——在 .git/refs/heads/ 目录下就是一个小文件,里面存着 commit 的 hash 值。
一个 Git 仓库可以有无数个分支,但有个关键限制:同一时刻工作目录只能检出一个分支。切换分支的时候,Git 会改写你工作目录里的所有文件。
Worktree 是什么?
Worktree 是实际存放文件的工作目录。默认情况下一个仓库只有一个 worktree,就是你 clone 下来的那个文件夹。
git worktree add 命令允许你为同一个仓库创建多个独立的工作目录,每个目录可以检出不同的分支。
两者对比一目了然
| 对比项 | 分支 | Worktree |
|---|---|---|
| 本质 | 指向 commit 的指针 | 实际的文件目录 |
| 数量限制 | 可以无限多 | 每个分支同时只能被一个 worktree 检出 |
| 切换成本 | 需要 stash/commit 未保存改动 | 不需要切换,直接 cd 过去 |
| 开销 | 几乎为零 | 占用磁盘空间(一份工作文件) |
一个形象的比喻
分支像是书签——你可以在书里夹无数个书签,但同时只能翻开一页来读。
Worktree 像是同一本书的多份副本——每份可以翻到不同的页同时阅读,但内容(Git 历史)是共享的。
二、Worktree 是不是”复制一份项目”?
很多人第一次看到 worktree 创建新目录,都会问这个问题。答案是:表面像,本质不是。
关键区别:worktree 只复制工作文件,不复制 .git 仓库本身。
普通 clone(真的复制)
project-a/
├── .git/ ← 完整的 Git 历史(可能几百 MB)
└── src/, ... ← 工作文件
project-b/ ← 完全独立的另一份
├── .git/ ← 另一份完整的 Git 历史
└── src/, ...
Worktree(共享 .git)
project/ ← 主 worktree
├── .git/ ← 完整的 Git 仓库
└── src/, ... ← 检出 main 分支的文件
project-feature/ ← 新增 worktree
├── .git ← ⚠️ 这是个文件,不是文件夹!内容是指向主 .git 的路径
└── src/, ... ← 检出 feature-a 分支的文件
这带来四个重要特性
1. 磁盘占用小 Git 历史只有一份。500MB 的 .git clone 两次就是 1GB,但 worktree 只多占工作文件的空间。
2. 提交历史实时共享 在 worktree A 里 git commit 后,立刻在 worktree B 里 git log 就能看到。不需要 push/pull。
3. 同一分支不能双开 Git 会阻止两个 worktree 同时检出同一分支,防止改乱。
4. 必须用专门命令删除 不能直接 rm -rf 或者资源管理器删文件夹,要用 git worktree remove。
三、实战演练:10 个练习带你上手
下面的练习请跟着一步步敲,所有命令在 Windows 的 Git Bash 或 PowerShell 下都能运行。
准备工作
建议在一个空目录里练习:
cd C:\Users\你的用户名\Desktop
mkdir worktree-practice
cd worktree-practice
# 初始化一个新仓库
git init demo
cd demo
# 做几次提交,让仓库有点内容
echo "Hello" > README.md
git add .
git commit -m "initial commit"
echo "version 1" > app.txt
git add .
git commit -m "add app.txt"
# 建两个分支,方便后面演示
git branch feature-a
git branch feature-b
现在你有一个仓库,三个分支:main、feature-a、feature-b。
练习 1:查看当前 worktree
git worktree list
输出类似:
C:/Users/.../demo abc1234 [main]
目前只有一个——就是你所在的主 worktree。
练习 2:添加第一个 worktree
为 feature-a 分支创建独立的工作目录:
# 语法:git worktree add <路径> <分支名>
git worktree add ../demo-feat-a feature-a
Git 会在上级目录创建 demo-feat-a 文件夹,里面自动检出 feature-a 分支的文件。
再查看一次:
git worktree list
现在有两条记录了。
练习 3:在新 worktree 里工作
# 切到新 worktree
cd ../demo-feat-a
# 确认当前分支
git branch --show-current # feature-a
# 做点改动并提交
echo "feature a work" > feature-a.txt
git add .
git commit -m "work on feature a"
git log --oneline
练习 4:见证”共享 .git”的神奇之处
# 切回主 worktree
cd ../demo
# 当前仍在 main 分支
git branch --show-current # main
# 但能立刻看到 feature-a 上刚才的 commit
git log feature-a --oneline
无需 push/pull,commit 立刻在两边同步可见——这就是共享 .git 的威力。
练习 5:体验”同一分支不能双开”
git worktree add ../demo-feat-a-2 feature-a
会报错:
fatal: 'feature-a' is already checked out at ...
这是故意的——Git 防止你同时在两个地方改同一分支造成混乱。
练习 6:创建新分支 + worktree(一步到位)
这是最常用的操作:开新分支同时放到新目录。
# -b 参数:新建分支并检出到新 worktree
git worktree add -b hotfix ../demo-hotfix main
意思是:基于 main 新建 hotfix 分支,检出到 ../demo-hotfix 目录。
cd ../demo-hotfix
git branch --show-current # hotfix
练习 7:临时查看某个历史版本
想看看某个旧 commit 的代码,但不想污染分支名:
cd ../demo
git log --oneline # 找到想看的 commit hash
# --detach:创建不绑定分支的临时 worktree
git worktree add --detach ../demo-inspect <commit的hash>
cd ../demo-inspect
# 这里的文件是那个 commit 时刻的快照,随便看随便测试
练习 8:正确删除 worktree
⚠️ 不要用资源管理器直接删文件夹,会留下残留元数据!
正确做法:
# 回到主 worktree(不能在要删的 worktree 里面执行)
cd ../demo
git worktree remove ../demo-inspect
git worktree remove ../demo-hotfix
如果 worktree 里有未提交的改动,remove 会拒绝,加 --force 强制删除:
git worktree remove --force ../demo-hotfix
练习 9:清理残留元数据
如果不小心手动删了 worktree 文件夹,Git 还会记得它:
git worktree prune
执行后 git worktree list 就干净了。
练习 10:实战场景演练
模拟真实场景:正在 feature-a 开发,突然线上有 bug 要修 main。
cd ../demo-feat-a
# 假装在写一半的代码(未 commit)
echo "work in progress" >> feature-a.txt
# 传统方式需要 stash 或强行 commit
# 但用 worktree,直接开新的!
cd ../demo
git worktree add -b hotfix-urgent ../demo-hotfix main
cd ../demo-hotfix
# 在这里专心修 bug
echo "bug fixed" > fix.txt
git add .
git commit -m "urgent fix"
# 修完了,切回原来的工作
cd ../demo-feat-a
cat feature-a.txt # "work in progress" 还在!
这就是 worktree 最大的价值——上下文无缝切换,写到一半的代码完好保留。
四、修完的 hotfix 怎么合并回 main?
Worktree 不改变合并逻辑,流程和普通分支合并完全一样。
基本合并流程
# 切到主 worktree(main 分支所在那个)
cd ../demo
git branch --show-current # main
# 合并
git merge hotfix-urgent
完成。git log --oneline 可以看到 hotfix 的 commit 已经进入 main 的历史。
合并后清理(顺序很关键)
必须先删 worktree,再删分支:
git worktree remove ../demo-hotfix # 1. 先删 worktree
git branch -d hotfix-urgent # 2. 再删分支
反过来 Git 会报错说分支还被 worktree 占用。
三种常见的合并方式
方式 1:普通 merge(会产生合并 commit,保留分叉历史)
git merge hotfix-urgent
方式 2:Fast-forward(线性历史)
如果 main 分出 hotfix 后没有新 commit,默认就是 fast-forward——直接把 main 指针挪到 hotfix 的最新 commit。
git merge --no-ff hotfix-urgent # 强制产生合并 commit
git merge --ff-only hotfix-urgent # 只允许 fast-forward,否则失败
方式 3:Rebase 后合并(最干净的历史)
cd ../demo-hotfix
git rebase main # 把 hotfix 基于最新 main 重放
cd ../demo
git merge hotfix-urgent # 此时必然是 fast-forward
⚠️ 已推送到远程并被他人拉过的分支不要 rebase,会出问题。
推荐的完整流程
cd ../demo
git checkout main
git merge --no-ff hotfix-urgent # 保留合并点方便追溯
git worktree remove ../demo-hotfix # 清理 worktree
git branch -d hotfix-urgent # 清理分支
git push origin main # 推送(如果有远程仓库)
处理合并冲突
git merge hotfix-urgent
# CONFLICT (content): Merge conflict in xxx.txt
处理步骤:
# 1. 查看冲突文件
git status
# 2. 打开冲突文件,会看到这样的标记:
# <<<<<<< HEAD
# main 的内容
# =======
# hotfix 的内容
# >>>>>>> hotfix-urgent
# 手动编辑成想要的样子,删掉所有 <<<、===、>>> 标记
# 3. 标记为已解决
git add xxx.txt
# 4. 完成合并
git commit
# 想放弃合并就用
git merge --abort
五、常用命令速查表
收藏这张表,用的时候直接查:
# 查看
git worktree list # 列出所有 worktree
# 创建
git worktree add <路径> <分支> # 为现有分支加 worktree
git worktree add -b <新分支> <路径> <起点> # 新建分支并加 worktree
git worktree add --detach <路径> <commit> # 临时查看某个 commit
# 删除
git worktree remove <路径> # 删除 worktree
git worktree remove --force <路径> # 强制删除(有未提交改动时)
git worktree prune # 清理已被手动删除的残留元数据
六、Windows 用户特别提示
-
路径分隔符:Git 命令里
/和\都能用。Git Bash 推荐/,PowerShell 推荐\。 -
删不掉 worktree 怎么办:大概率是 VS Code 之类的 IDE 还开着那个文件夹,关掉再删。
-
推荐用 Git Bash:本文所有命令在 Git Bash 里体验最一致。PowerShell 也能跑,但
echo等少数命令行为略有不同。
七、最佳实践总结
经过练习,这几条建议能让你少踩坑:
-
合并操作永远在主 worktree 里做,不要在临时 worktree 里 merge
-
命名要有规律,比如
项目名-分支名(demo-feat-a、demo-hotfix),方便辨识 -
用完立刻清理,别让废弃的 worktree 堆积
-
牢记删除顺序:先
worktree remove,再branch -d -
不要用文件管理器直接删 worktree 目录,要用 Git 命令
结语
git worktree 是 Git 里一个被严重低估的功能,特别适合以下场景:
-
多分支并行开发
-
紧急 bug 修复不打断当前工作
-
Code review 时独立环境跑别人的代码
-
多个 AI agent(比如 Claude Code)并行工作避免冲突
掌握它之后,你会发现 git stash 的使用频率大大降低,工作流程顺畅很多。
跟着本文的练习走一遍,worktree 就彻底拿下了。如果觉得有用,点赞收藏支持一下











暂无评论内容