在日常开发中,我们经常遇到这样的场景:正在一个复杂的功能分支(feature-X)上深入开发,突然一个生产环境的紧急 Bug(Hotfix)警报响起。传统的做法是:使用 git stash 暂存当前工作,切换到主分支或热修复分支,进行修复、提交、推送,然后再切回 feature-X,最后使用 git stash pop 恢复工作。这个过程虽然有效,但频繁的上下文切换非常耗费心神。
Git Worktree 提供了一个优雅的解决方案。它允许你为同一个 Git 仓库创建多个独立的工作目录(Working Tree),每个目录可以检出到不同的分支,且互不干扰。这就像你在不克隆仓库的情况下,拥有了仓库的多个实时视图。
什么是 Git Worktree?
git worktree 是 Git 2.5 版本引入的特性。它允许你创建一个附加的、链接到同一个 Git 仓库的克隆目录。所有的工作树都共享核心的 Git 对象数据库(.git 目录下的对象),但拥有各自独立的工作副本和索引文件。
实践:使用 Worktree 处理紧急 Bug
我们通过一个实际案例来演示如何利用 worktree 来实现零中断的 Hotfix 流程。
步骤一:初始化项目并创建功能分支
假设我们正在 feature/new-design 分支上工作。
mkdir project_main
cd project_main
git init
echo "Initial setup" > README.md
git add .
git commit -m "Initial commit"
# 创建并切换到功能分支
git checkout -b feature/new-design
echo "Developing feature X" >> feature.txt
# 查看当前工作区列表
git worktree list
# /path/to/project_main (HEAD attached)
步骤二:创建用于热修复的 Worktree
现在,紧急 Bug 来了,我们需要在 hotfix/critical-bug 分支上进行修复,但不想离开 project_main 目录(我们正在编写的功能代码)。
我们将在项目目录的同级目录下创建一个新的工作目录,名为 project_hotfix,并让它自动检出到一个新的分支 hotfix/critical-bug。
# 注意:我们仍在 project_main 目录中执行此命令
# 假设主仓库在 /path/to/project_main
# 新的工作区将创建在 /path/to/project_hotfix
git worktree add ../project_hotfix hotfix/critical-bug
# 检查工作区状态:现在有两个工作区
git worktree list
# /path/to/project_main 9e8d327 [feature/new-design]
# /path/to/project_hotfix 9e8d327 [hotfix/critical-bug]
步骤三:在两个工作区并行工作
现在你可以完全独立地在两个目录下工作。
1. 在 Hotfix 目录中修复 Bug:
cd ../project_hotfix
echo "Applying critical fix" > fix_code.js
git add .
git commit -m "Hotfix: Resolved critical bug in production"
# 推送修复
git push origin hotfix/critical-bug
2. 回到主目录继续功能开发:
cd ../project_main
# 检查:feature.txt 中的内容和索引状态都未曾改变
cat feature.txt
# 继续开发 feature/new-design
echo "More feature progress" >> feature.txt
# ... 你的工作完全不受 hotfix 目录的影响
注意:如果主目录下的分支(feature/new-design)与热修复目录下的分支(hotfix/critical-bug)处于不同的状态,Git 不会让你在两个工作区同时检出同一个分支。这是 worktree 机制的核心保护。
步骤四:清理工作区
一旦热修复分支(hotfix/critical-bug)被合并到 main 分支并完成使命,你可以安全地移除这个临时的工作区。
# 确保你不在 project_hotfix 目录下时执行移除操作
cd ../project_main
# 移除工作区目录。此操作也会删除磁盘上的 project_hotfix 文件夹
git worktree remove ../project_hotfix
# 再次检查工作区列表
git worktree list
# 只剩下 /path/to/project_main
如果工作区包含未提交的更改,git worktree remove 会失败,此时你需要使用 -f 强制删除(但不推荐,除非你确定不需要那些更改),或者先在临时工作区提交/暂存。
总结
git worktree 是一个强大的工具,它通过提供隔离的工作环境,极大地提升了处理并发任务时的效率和心智负担。告别频繁的 stash 和 checkout,让你的紧急修复流程更加丝滑顺畅。
汤不热吧