git worktree 和 branch 有什么区别?各自什么时候用
branch 是一串 commit 的名字,worktree 是检出某个分支的目录。什么时候切分支、什么时候加 worktree,以及 stash 和 clone 该怎么比。
一句话回答:branch(分支)是指向一串 commit 的可移动名字;worktree 是磁盘上检出某个分支的目录。两者不是二选一:每个 worktree 都检出着一个分支(或 detached HEAD)。真正的选择是:在一个目录里来回切分支,还是给每个分支一个自己的目录。
分支是什么
分支是一个指针:.git/refs/heads/ 下的一个文件,里面存着一个 commit ID,每次提交都会往前移。建分支不花成本,也不改任何文件。在普通的 clone 里,你一次只看到一个分支,git switch 会把目录里的文件改成目标分支的样子。
worktree 是什么
worktree 是挂在同一个仓库上的额外工作目录。它有自己的文件、暂存区和 HEAD,但和主目录共用 commit、分支和配置。有了 worktree,你可以同时检出多个分支,每个在自己的目录里。
对比
| 切换分支 | 每个分支一个 worktree | |
|---|---|---|
| 磁盘上的目录 | 一个 | 每个分支一个 |
| 同时打开的分支 | 一个 | 多个 |
| 切换时的未提交改动 | 得先提交或 stash | 留在自己的目录里不动 |
| 依赖和构建缓存 | 多次切换后要重建 | 每个目录装一次 |
| 磁盘占用 | 最少 | 多出检出的文件,加上每个目录的依赖 |
| 同一分支在两处检出 | 不涉及 | 不允许 |
| 适合 | 短小、顺序进行的任务 | 并行工作、长时间构建、AI agent |
什么时候切分支就够了
- 一次只做一件事,做完再开始下一件。
- 项目构建很快,每个分支没有很重的依赖。
- 需要切换时,很少有没提交的工作。
什么时候 worktree 更好
- 被打断。功能做到一半来了个紧急修复,开一个 main 的 worktree,不用 stash 半成品。
- 审查 PR的同时,自己的分支保持原样,开发服务器也不用停。
- 长时间任务。一个目录跑测试或构建,另一个目录继续写代码。
- AI 编码 agent。Claude Code、Codex 等会直接改文件,每个都需要自己的目录。见并行运行多个 agent和 claude --worktree 用法。
那 stash 和 clone 呢?
stash 把未提交的改动暂存起来,让你在同一个目录里切分支。临时绕一下很好用,但 stash 容易被忘掉,而且同一仓库的所有 worktree 共享同一份 stash。再 clone 一份也能得到另一个目录,但历史是单独的一份:两份之间要 fetch、push 来同步,一边的分支另一边也看不到。worktree 给你单独的目录,却不用单独的仓库。
worktree 的代价
目录建起来容易,忘起来也容易。一个月下来,可能有十几个 worktree:有的已经合并,有的 commit 只在你电脑上,有的有没人提交的改动。Orchard 把你 Mac 上所有 worktree 放进一个视图,告诉你哪些还有工作、哪些已经进了 main。想手动清理,可以用清理清单。
常见问题
git worktree 和分支是一回事吗?
不是。分支是指向 commit 的名字,worktree 是检出某个分支的目录。只有一个 worktree 也可以有很多分支,但每多一个 worktree,就需要它自己的分支或 detached HEAD。
两个 worktree 能检出同一个分支吗?
不能。git 只允许一个分支同时在一个 worktree 里检出,并提示这个分支已被另一个 worktree 使用。可以用另一个分支,只读的话用 detached HEAD。
该用 git worktree 还是 git stash?
在同一个目录里临时绕几分钟,用 stash。另一件事要做得更久、需要自己的构建或开发服务器,或者有 AI agent 同时在做,就用 worktree。