工具大全
开发者工具作者:Coocon2026年9月12日3 次阅读约 5 分钟阅读

改到一半要修线上 bug?别 git stash,用 git worktree 再开一个目录

写到一半,群里一句「线上挂了,你看下」。你手里是一堆没提交的改动,测试还没跑通,现在要切到 main 上修一个 bug。

肌肉记忆告诉你:git stash,切分支,修完,切回来,git stash pop。这条路我走了很多年,每一步都踩过坑。后来发现 Git 早就给了另一条路:同一个仓库,再开一个目录,检出另一个分支。改到一半的东西原地不动,修 bug 去隔壁做。这就是 git worktree

stash 到底哪里不对

先说清楚,stash 不是坏东西,是被用错了场景。它设计出来是「临时把工作区收起来」,不是「在两个任务之间来回切」。用它切任务,有四个具体的坑:

第一,默认不带未跟踪文件。 你新建的文件不在 stash 里,切到 main 后它们还躺在工作区。修 bug 时一不留神就把它们一起提交进去。要带上得加 -u,要连 .gitignore 里的一起带得加 -a,很少有人每次都记得。

第二,pop 回来会冲突。 你在 main 上修的那几行,恰好也是你 feature 分支改过的地方,git stash pop 直接给你一屏冲突标记。这时候 stash 条目还在(pop 失败不会删),你得手动解冲突再 git stash drop,不少人在这一步把改动弄丢过。

第三,stash 是本地的,不进远端。 换台机器、仓库重新 clone、误删目录,stash 全没了。它不像分支可以 push。

第四,忘掉的 stash 会堆成坟场。 跑一下 git stash list,很多人能翻出十几条「WIP on feature-xxx」,没人记得里面是什么,也没人敢删。

这四条的根源是同一个:stash 试图在一个工作区里装两件事。解法不是把 stash 用得更熟,是再开一个工作区。

worktree 是什么

git worktree 让一个仓库同时拥有多个工作目录。每个目录检出各自的分支,有各自的 HEAD、各自的暂存区,但共享同一份对象库和分支列表。你在任何一个目录里提交,其他目录立刻能看到这个提交。

一句话记:clone 是复制仓库,worktree 是复制工作区。 对象库只有一份,不占双倍磁盘,也不用来回 fetch。

回到开头的场景,现在的做法是:

# 在主目录(feature 分支,一堆没提交的改动)里执行
git worktree add ../myproj-hotfix main

Git 在上一级目录创建 myproj-hotfix,里面检出的是 main。你 cd 过去修 bug、提交、push,再 cd 回来,主目录的一切还是你离开时的样子。没有 stash,没有 pop,没有冲突。

修完删掉:

git worktree remove ../myproj-hotfix

四条命令够用了

# 1. 基于已有分支开一个目录
git worktree add <路径> <分支>

# 2. 顺手新建分支再开目录(最常用)
git worktree add -b hotfix/login-500 ../myproj-hotfix main

# 3. 看看现在有哪些工作区
git worktree list

# 4. 用完删掉(目录里有未提交改动会拒绝,加 --force 强删)
git worktree remove <路径>

git worktree list 的输出长这样:

/Users/you/myproj          a1b2c3d [feature/new-editor]
/Users/you/myproj-hotfix   e4f5g6h [hotfix/login-500]

再补一条:如果你直接 rm -rf 了工作区目录而没走 remove,Git 的记录里还留着它,跑 git worktree prune 清理。

一个必踩的限制:同一个分支不能开两次

$ git worktree add ../myproj-2 feature/new-editor
fatal: 'feature/new-editor' is already checked out at '/Users/you/myproj'

一个分支同时只能出现在一个工作区里。 这不是 bug,是保护:两个目录改同一个分支,HEAD 会互相踩。你要么新建分支,要么用 --detach 检出一个游离的提交只读看看。

它的原理,以及为什么不占地方

进新开的目录看一眼,会发现 .git 不是目录,是一个文件:

$ cat ../myproj-hotfix/.git
gitdir: /Users/you/myproj/.git/worktrees/myproj-hotfix

它指回主仓库的 .git/worktrees/ 下面的一个子目录,里面只放这个工作区私有的东西:HEADindexlogs。对象库、分支引用、配置、hooks 都还在主仓库那份 .git 里,所有工作区共用。

所以多开一个 worktree 的成本是一份检出的源码,不是一份仓库。对一个几十 MB 源码、几个 GB 历史的项目来说,几乎等于免费。

node_modules 怎么办

这是前端同学问得最多的。新目录是一份干净的源码,node_modules 不在里面,你得再装一遍。

三个层面看这件事:

它是代价,但也是正确性。 main 和你的 feature 分支依赖版本可能不同,共用一份 node_modules 本来就是错的。stash 方案里你一直在用 feature 分支的依赖跑 main 的代码,只是没出事而已。

用 pnpm 的话这个代价接近零。 pnpm 的依赖存在全局内容寻址仓库里,每个项目目录只是硬链接。第二个 worktree 里 pnpm install 基本是秒级,磁盘不翻倍。

用 npm 的话给 hotfix 开个专用 worktree 长期留着。 不要每次修 bug 都建了删、删了建。留一个 ../myproj-main 目录常驻 mainnode_modules 装一次,之后每次修 bug 直接 cd 过去 git pull

什么时候还是该用 stash

worktree 不是要消灭 stash。两个场景 stash 仍然更顺手:

  • 只是想临时看一眼干净的工作区,比如确认某个 bug 是不是自己改出来的。git stash 看完 git stash pop,前后不到一分钟,不值得开目录。
  • 改动要跟着分支走。 你在错误的分支上写了半天,想把改动挪到正确的分支。这是 stash 的本职:git stash,切过去,git stash pop

判断标准就一条:这件事要不要在另一边停留超过十分钟。 会停留,开 worktree;不会,用 stash。

顺便说一句:AI 编码工具也在这么用

Claude Code、Cursor 这类工具让多个 Agent 并行改同一个仓库时,用的正是 worktree:每个任务一个目录、一个分支,互不干扰,做完再合并。Claude Code 的文档里直接把「用 git worktree 跑多个并行会话」写成了推荐工作流。原因和你修 bug 是一样的,一个工作区装不下两件事。

如果你打算让 AI 帮你并行干活,先把 worktree 用熟,会省很多「它把我改到一半的文件覆盖了」的事故。

今天就能做的事

把下面这条加到你的 shell 别名里:

# ~/.zshrc 或 ~/.bashrc
alias gwa='git worktree add'
alias gwl='git worktree list'
alias gwr='git worktree remove'

下次群里再喊「线上挂了」,你的动作是三步:gwa ../hotfix main,修,gwr ../hotfix。手里那堆改动,从头到尾没动过。

最后问一句:你现在的 git stash list 里有几条?超过三条的,评论区报个数。

相关文章

GitHub 宕机 7 个半小时那天,Cursor 发布了自己的代码托管平台

8 月 17 日 GitHub 经历了 7 小时 35 分的 critical 级事故——这是它两个月内的第 9 次 critical。同一天,Cursor 发布代码托管平台 Origin。一边是耐心耗尽的 Hacker News 认真讨论搬家,一边是带着 SpaceX 600 亿美元资本入场的挑战者。护城河开始松动了吗?我们把两件事的数据都核了一遍。

开发者工具github+4
developer2026年8月18日6 min
249

Claude Code Plan Mode 实战:先规划后动手,把返工率打下来

Plan Mode 是 Claude Code 的只读规划模式:先调研代码库、产出实施方案,经你批准后才动手改代码。本文讲清怎么进入 Plan Mode(Shift+Tab 循环切换)、它到底拦住了什么、什么任务该用什么任务不该用,以及让规划真正提质量的四个技巧。

claude-codeplan-mode+4
claude2026年7月28日3 min
255

npm install 会改你的 package-lock.json:CI 必须用 npm ci 的 3 个理由

npm install 和 npm ci 的区别,一半人会答成「后者快一点」。真正的区别是:npm install 有权改写 package-lock.json,npm ci 没有。本文用三个真实场景讲清这个差别为什么在 CI 里是致命的——lock 文件被镜像源来回翻转、macOS 生成的 lock 在 Linux 上缺二进制依赖、package.json 手改后 lock 静默失步——以及 yarn、pnpm 对应的命令是什么。

cicdnodejs+5
developer2026年9月12日4 min
2

CLAUDE.md 不是 README:给 Claude Code 写规则的 5 条硬规矩

很多人把 README 或架构文档整个贴进 CLAUDE.md,结果 Claude Code 该守的规矩不守、不该改的文件乱改。原因是 CLAUDE.md 不是文档,是每一轮对话都常驻上下文的指令。本文给 5 条硬规矩:只写代码里推不出来的东西、越短越管用、硬规则交给 hooks 不靠文字、按层级拆文件、被纠正后当场回写。附一份可直接抄的骨架。

claude-code提示词+4
developer2026年9月12日4 min
3