代码改了一半,暂时还不想提交,却需要去另一个分支修问题。常见做法是先stash,修完再恢复。这当然能用;麻烦在于,你得把当前现场收起来,再重新找回来。
Git Worktree 提供了另一种做法:当前目录先留着,再开一个目录处理另一个分支。两个任务各有自己的工作文件和暂存区,你可以分别打开编辑器。
下面用一个最小仓库演示。示例里的“修复”只是修改配置,目的是看清 Git 的行为,不涉及真实线上系统。命令在 Windows、PowerShell 7.5.4 和 Git 2.55.0.windows.5 下跑过。
先做出一个切不走的现场
找一个空目录执行下面的命令。演示会创建worktree-demo/shop-app,不要放到已有项目里运行。
mkdir worktree-demo cd worktree-demo git init-b main shop-app cd shop-app# 只设置这个演示仓库的提交身份git config--local user.name"Worktree Demo"git config--local user.email"demo@example.invalid"@("feature.search=off","checkout.retries=1")|Set-Contentapp.properties-Encoding utf8NoBOM git add app.properties git commit-m"initial configuration"git branch feature/search# main 分支随后有了一次配置变更@("feature.search=off","checkout.retries=3")|Set-Contentapp.properties-Encoding utf8NoBOM git add app.properties git commit-m"adjust checkout retries on main"# 回到功能分支,留下尚未提交的修改gitswitchfeature/search @("feature.search=on","checkout.retries=1")|Set-Contentapp.properties-Encoding utf8NoBOM git status--short--branch这时所在分支是feature/search,app.properties有未提交的改动:
## feature/search M app.properties再执行git switch main,会得到这段提示:
error: Your local changes to the following files would be overwritten by checkout: app.properties Please commit your changes or stash them before you switch branches. Aborting这里特意让两个分支修改同一个文件,是为了稳定复现保护机制。并不是只要工作区不干净,Git 就一定拒绝切分支;会覆盖当前修改时,它才会拦住这次操作。
当前目录不动,给修复分支另开一个目录
仍在shop-app中执行:
git worktree add-b fix/checkout../shop-hotfix main git worktree list这条命令里,main是新分支的起点,fix/checkout是要创建的分支,../shop-hotfix是它的工作目录。
如果分支已经存在,才使用不带-b的写法,例如git worktree add ../shop-hotfix fix/checkout。不要混用:前一种创建分支,后一种检出已有分支。
此时目录关系是这样:
6秒原创机制示意动画。工作文件、暂存区和 HEAD 各自独立,对象库与大部分引用共享;动画按实验中的目录关系绘制。
分别查看两个目录中的配置:
Get-Content./app.propertiesGet-Content../shop-hotfix/app.properties本次实验中,前者是feature.search=on、checkout.retries=1,后者是feature.search=off、checkout.retries=3。原目录的功能改动还在,新目录拿到的是main那份已提交的内容。
现在就可以用 IDEA 或其他编辑器打开shop-hotfix。两个目录都能继续操作,不必先把功能分支里的半成品塞进一次临时提交。
修完后,别忘了把提交交回主线
下面继续修改演示配置,并在修复分支提交:
@("feature.search=off","checkout.retries=4")|Set-Content../shop-hotfix/app.properties-Encoding utf8NoBOM git-C../shop-hotfix add app.properties git-C../shop-hotfix commit-m"fix checkout retry limit"git status--short--branch最后一个命令查看的仍是原来的shop-app。它依然显示feature/search和那处未提交修改。修复提交已经在fix/checkout上,但不会因此自动进入main。
本次真实 VS Code 截图。左侧是功能分支保留的修改,右侧是已将重试次数改为 4 并提交的修复目录;侧栏的名称用于区分两个工作目录。
实际项目还是要走团队原有的评审、合并和测试流程。Worktree 帮你安排工作目录,不能替你决定合并什么。
用完可以移除目录,分支还在
先确认修复目录里的改动已经妥善处理:
git-C../shop-hotfix status--short--branch git worktree remove../shop-hotfix git worktree list git branch--list本次实验中,移除后只剩shop-app这个工作目录,fix/checkout分支和刚才的提交仍然存在。移除 Worktree 不等于删除分支。
remove默认也会检查未提交修改和未跟踪文件。遇到拒绝移除,先去看git status,不要为了省一步直接加--force。这个演示最后保留了原目录的未提交修改,方便继续核对;它没有被清理命令顺手抹掉。
“各开一个目录”也有边界
每个 Worktree 有自己的工作文件、暂存区和HEAD,但它们属于同一个仓库,共享对象库和大部分引用。默认情况下,同一分支已经被一个 Worktree 使用,另一个就不能再检出它。本次尝试再次检出feature/search时,Git 返回了already used by worktree。
这也是为什么给多个 AI 编程任务分目录时,应该给它们安排不同分支,并明确谁负责最后合并。目录分开,并没有消除代码层面的冲突。
运行环境也要另外安排。两个 Spring Boot 项目如果都监听同一个端口,还是会冲突;连接同一个数据库,也可能改到同一份数据。依赖目录和构建产物通常还要分别准备,不能把 Worktree 当成容器。
如果只是临时离开几分钟,stash很顺手。如果两个任务需要并排看代码、来回调试,或者要让多个 Agent 分头改不同功能,再开 Worktree 会更合适。判断的依据是你是否需要同时保留两个工作现场。
修订于2026年11月1日:补完整最小仓库、失败与收尾结果、真实IDE截图和原创关系动画,并区分工作目录与运行环境隔离。
参考:Git 官方 git-worktree 文档。