Git Worktree:在不打断当前开发的情况下紧急修复生产问题
背景
你正在 feature/new-dashboard 分支上埋头开发新功能,代码改了一半,到处是未完成的状态。这时候 Slack 响了:生产环境挂了。
传统做法是 git stash 或临时 commit,然后切换分支------但这会打乱你的工作状态,事后还要恢复现场。
Git Worktree 提供了一个更优雅的方案:同一个仓库,同时检出多个分支到不同目录,互不干扰。
什么是 Git Worktree
Git 仓库默认只有一个工作目录(Working Tree)。git worktree 命令允许你从同一个 .git 仓库,额外创建多个关联的工作目录,每个目录可以独立检出不同分支。
my-project/ ← 主工作目录(feature/new-dashboard)
my-project-hotfix/ ← 新增工作目录(hotfix/prod-crash)
两个目录共享同一个 .git,本地提交、分支、stash 全部互通,但工作区完全隔离。
实战演练
场景还原
项目根目录:~/projects/my-app
当前分支:feature/new-dashboard(有大量未提交改动)
生产分支:main
第一步:创建 hotfix worktree
bash
# 在项目根目录执行
git worktree add ../my-app-hotfix main
这条命令做了两件事:
- 在
../my-app-hotfix创建一个新的工作目录 - 将
main分支检出到该目录
此时你的目录结构:
~/projects/
├── my-app/ ← 原工作目录,feature 分支,改动完好保留
└── my-app-hotfix/ ← 新工作目录,干净的 main 分支
第二步:切换到 hotfix 目录开始修复
bash
cd ../my-app-hotfix
# 创建 hotfix 分支
git checkout -b hotfix/prod-crash
# 安装依赖(如果项目需要)
npm install
# 定位问题、修改代码...
vim src/api/payment.ts
# 提交修复
git add .
git commit -m "fix: 修复支付接口空指针崩溃"
第三步:部署修复
bash
# 合并回 main 并推送
git checkout main
git merge hotfix/prod-crash
git push origin main
# 或者直接推送 hotfix 分支,走 CI/CD 流程
git push origin hotfix/prod-crash
第四步:回到原来的工作
bash
cd ~/projects/my-app
# 一切如旧,feature 分支的改动原封不动
第五步:清理 worktree
修复完成后,清理掉临时工作目录:
bash
# 回到主目录执行
git worktree remove ../my-app-hotfix
# 同时删除 hotfix 分支(可选)
git branch -d hotfix/prod-crash
常用命令速查
bash
# 添加 worktree(检出已有分支)
git worktree add <路径> <分支名>
# 添加 worktree(同时创建新分支)
git worktree add -b <新分支名> <路径> <起点>
# 查看所有 worktree
git worktree list
# 删除 worktree
git worktree remove <路径>
# 强制删除(有未提交改动时)
git worktree remove --force <路径>
# 清理已手动删除的 worktree 记录
git worktree prune
注意事项
同一分支只能被一个 worktree 检出。 如果你想在 hotfix 目录检出 main,主目录就不能同时在 main 上------否则报错:
fatal: 'main' is already checked out at '/path/to/my-app'
解决方式:主目录保持在 feature 分支,hotfix 目录检出 main,不冲突。
node_modules 不共享。 每个 worktree 是独立的文件系统目录,依赖需要单独安装。对于大型项目,可以用软链接或 npm link 加速,或者直接用 pnpm(天然支持 symlink 共享)。
.env 等配置文件需要手动复制。 worktree 不会自动复制被 .gitignore 忽略的文件。
对比其他方案
| 方案 | 优点 | 缺点 |
|---|---|---|
git stash |
简单快速 | 切换分支后环境改变,恢复现场需要手动操作 |
| 临时 commit | 保留了改动 | 污染提交历史,需要事后 reset |
| 克隆新仓库 | 完全隔离 | 占用双倍磁盘,不共享 Git 历史 |
| git worktree | 共享 Git 数据,目录完全隔离,无需切换 | 依赖需独立安装 |
总结
git worktree 非常适合这类场景:
- 生产环境紧急 hotfix,不想 stash 打断开发节奏
- 同时对比两个分支的运行效果
- 跑耗时的测试/构建,同时继续写代码
对于 Web 开发者来说,掌握这个命令能让你在多任务切换时游刃有余,不再被"先把手头的事收个尾"所困扰。