Git Worktree 保姆级教程:AI编程必备技能!带你熟练掌握!

前言

你有没有遇到过这种情况——

正在 feature-a 分支上写代码写得正起劲,产品经理突然跑过来:”线上 bug!马上修!”

这时候你只有两个选择:

  1. git stash 存一下,切到 main,修完 bug,再切回来,git stash pop 恢复现场

  2. 硬着头皮 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

现在你有一个仓库,三个分支:mainfeature-afeature-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 用户特别提示

  1. 路径分隔符:Git 命令里 / 和 \ 都能用。Git Bash 推荐 /,PowerShell 推荐 \

  2. 删不掉 worktree 怎么办:大概率是 VS Code 之类的 IDE 还开着那个文件夹,关掉再删。

  3. 推荐用 Git Bash:本文所有命令在 Git Bash 里体验最一致。PowerShell 也能跑,但 echo 等少数命令行为略有不同。


七、最佳实践总结

经过练习,这几条建议能让你少踩坑:

  • 合并操作永远在主 worktree 里做,不要在临时 worktree 里 merge

  • 命名要有规律,比如 项目名-分支名demo-feat-ademo-hotfix),方便辨识

  • 用完立刻清理,别让废弃的 worktree 堆积

  • 牢记删除顺序:先 worktree remove,再 branch -d

  • 不要用文件管理器直接删 worktree 目录,要用 Git 命令


结语

git worktree 是 Git 里一个被严重低估的功能,特别适合以下场景:

  • 多分支并行开发

  • 紧急 bug 修复不打断当前工作

  • Code review 时独立环境跑别人的代码

  • 多个 AI agent(比如 Claude Code)并行工作避免冲突

掌握它之后,你会发现 git stash 的使用频率大大降低,工作流程顺畅很多。

跟着本文的练习走一遍,worktree 就彻底拿下了。如果觉得有用,点赞收藏支持一下

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容