你以为自己需要更熟练地 stash,其实很多时候,你只是需要多一张干净的工作台。
做开发的人,大概都碰到过这种场景:
你正在一个分支上改到一半,测试还没跑完,突然有人让你帮忙看一个线上 bug。你切分支之前先看一眼 git status,发现工作区里有一堆没提交的文件。于是你开始纠结:要不要先 commit?commit 信息怎么写?要不要 stash?stash 之后会不会忘?如果当前分支还改了依赖、改了数据库迁移、改了配置文件,那切过去更像是在拆一张已经铺开的桌子。
git worktree 解决的就是这个问题。
它不是 Git 的隐藏魔法,也不用你换一套工作流。它就是 Git 官方给你的一个工具:同一个仓库,可以同时展开多个工作目录。每个目录可以检出不同的分支,互不打扰,但它们共享同一套 Git 对象库。
说人话:你不用把当前桌面收拾干净,直接在旁边再开一张桌子。
一、为什么很多人一直没用过它
git worktree 并不新。Git 2.5 发布时,它就已经作为正式功能出现了。只是这些年,大多数技术文档类的教程更常讲 checkout、switch、stash,很少把 worktree 放进日常工作流里。
这也能理解。
对初学者来说,Git 本来就够绕了。分支、暂存区、rebase、merge、remote 这些概念还没理顺,再加一个 worktree,好像只是增加认知负担。
但项目一复杂,它的价值就会变得很具体。
你可以保留正在开发的功能,另开一个目录修紧急 bug。
你也可以让当前分支继续跑测试,自己去另一个目录 review 同事的 PR。要对比两个版本,也不用来回切分支。
最近 AI 编程助手用得多了,worktree 还有个新用途:给每个 agent 单独开一个目录。它改它的,不污染你手上的工作区。
真正省下来的,是切换上下文时那点心理阻力。
很多开发效率不是输在写代码慢,而是输在切换前那几分钟犹豫:我现在能不能切?这些改动放哪?切回来会不会乱?worktree 把这件事变轻了。
二、它到底是什么
官方文档说,git worktree 用来管理多个附加到同一个仓库的工作树。
主工作树就是你平时 clone 下来的那个目录。额外创建出来的目录,叫 linked worktree。
看一个最小例子:
git worktree add ../project-hotfix hotfix/login-error
这条命令会在当前仓库旁边创建一个新目录 project-hotfix,并在里面检出 hotfix/login-error 这个分支。
如果这个分支还不存在,可以加 -b:
git worktree add -b hotfix/login-error ../project-hotfix main
这会从 main 新建一个 hotfix/login-error 分支,并把它放到 ../project-hotfix 这个新工作目录里。
进去之后,它看起来就像一个正常仓库:
cd ../project-hotfix
git status
你可以改代码、提交、跑测试、推远端。原来的目录不会动。那边该半成品还是半成品,该跑服务还是跑服务。
想查当前有哪些 worktree:
git worktree list
不用了就删掉:
git worktree remove ../project-hotfix
如果某个 worktree 的目录被你手动删掉了,Git 里还残留记录,可以清理一下:
git worktree prune
这几条命令就够用了。别急着背完整参数,先让它进入肌肉记忆。
三、什么时候用最顺手
最常见的是紧急修复。
你在 feature/payment 上改了一半,线上突然报错。以前你可能会:
git stash
git switch main
git switch -c hotfix/xxx
修完之后再 stash pop。如果冲突了,还要再收拾一遍。这个过程不难,就是烦。
用 worktree 就简单很多:
git worktree add -b hotfix/xxx ../project-hotfix main
你的功能分支留在原地,bug 修复在另一个目录里完成。两个任务的文件、依赖、编辑器窗口都分开,脑子不用跟着来回折腾。
第二种情况,是 review 和对比。
很多时候你只是想看一下别人的分支,跑一下测试,或者对照某个老版本。
直接切过去当然可以。但如果你当前分支状态复杂,切分支这件小事就会变得烦。
worktree 的好处是,你可以把 review 当成一个临时空间:
git fetch origin
git worktree add ../project-review origin/someone-branch
看完、测完、删掉。这个目录存在的目的很单纯,不需要和你自己的开发现场搅在一起。
还有一种情况,这两年越来越常见:多代理或 AI 辅助开发。
现在不少人会让不同的 AI agent 同时尝试不同方案。如果大家都在同一个工作区里改文件,很快就会乱。worktree 很适合给每个方案分配一个独立目录:
git worktree add -b try/cache-layer ../project-cache main
git worktree add -b try/ui-refactor ../project-ui main
每个目录就是一个独立实验场。最后哪个方案靠谱,再合回来。失败的方案直接删掉,主工作区里不用清理一堆残留文件。
四、它好用,但不是没有坑
worktree 最容易让人误会的一点是:它不是把整个仓库复制一份。
它会共享 Git 对象库,所以创建速度通常很快,也不会像完整 clone 那样重复保存所有历史对象。但工作目录里的依赖、构建产物、缓存文件,仍然是各自独立的。这个地方最容易踩坑。
如果你是 Node 项目,每个 worktree 可能都要有自己的 node_modules。
如果你是 Python 项目,虚拟环境最好也单独建。端口、数据库名、.env 配置,也要注意隔离。
这里有个实用习惯:把 worktree 都放在主仓库旁边,用统一命名。
比如:
my-app/
my-app.hotfix-login/
my-app.review-pr-123/
my-app.try-search/
一眼就知道哪个目录是干什么的。不要随手散落在桌面、下载目录、临时目录里。worktree 一多,目录管理本身也会变成麻烦。
还有一个 Git 层面的限制:同一个分支通常不能同时被两个 worktree 检出。
这个规则有点烦,但它确实能挡住一类混乱场面:两个目录同时改同一个分支。更稳妥的做法是给不同任务建不同分支,必要时再开临时分支。
如果你只是想临时看一眼某个 commit,也可以创建 detached HEAD 状态的 worktree。但日常开发里,我更建议明确建分支。分支名就是任务名,状态越明白,后面越省心。
五、怎么把它放进日常工作流
我建议从一个很小的习惯开始:凡是需要“临时切出去”的事,都先问自己一句,要不要开一个 worktree?
比如:
git worktree add -b hotfix/login ../my-app.hotfix-login main
修完之后:
cd ../my-app.hotfix-login
git push -u origin hotfix/login
cd ../my-app
git worktree remove ../my-app.hotfix-login
如果你经常用,可以给 shell 配个别名,减少输入成本。比如:
alias gwl='git worktree list'
alias gwr='git worktree remove'
但我不建议一开始就装一堆封装工具。先用原生命令跑几次,你会更清楚它到底在管理什么。等你真的觉得命令太长,再考虑脚本化。
还有一点很重要:worktree 不是用来逃避提交纪律的。
它能让多个任务分开,但每个任务内部仍然要有清楚的提交、明确的分支名、可复现的环境。
否则你只是把一个混乱工作区,变成了三个混乱工作区。
工具不会替你做工程判断,它只是把正确动作的成本降下来。
总结
学 git worktree,重点不在多记几条命令。它真正改变的是你处理上下文切换的方式。
以前你在一个工作目录里来回切分支,所有任务共享同一张桌子。现在你可以给不同任务开不同桌面:一个做功能,一个修 bug,一个 review,一个让 AI agent 试方案。
它特别适合中大型项目、多人协作、频繁 review 的团队。在云栈社区里,不少开发者都分享过类似的经验:当你的DevOps流程越来越复杂时,这种能够并行处理任务的能力就会显得尤为重要。
如果你还没用过,可以今天就试一次。找一个不重要的仓库,执行:
git worktree add -b test-worktree ../repo-test-worktree main
git worktree list
你会很快明白它的手感。
有些工具的价值不在复杂,而在顺手。git worktree 就是这种。
你平时更常用 stash,还是已经开始用 worktree 了?不妨重新审视一下自己的工作流,或许一个小小的改变就能带来巨大的效率提升。
来源:Git 官方文档 git-worktree、GitHub Blog《Git 2.5, including multiple worktrees and triangular workflows》、Tower Git FAQ《How to Work on Multiple Branches Simultaneously with Git Worktree》。