- CLI
- 0.2.17
- 预览 ref
- a2c45c8
Git worktree 看起来可能像是给“硬核” Git 用户的高级功能。
但同样的情况会一再出现:
- 你正在做一处改动
- 一个小的热修复突然冒出来
- 或者你需要快速审阅另一个分支
- 而你不想反复 stash/unstash
worktree 是对此很干净的解法。
第二个领悟更实际:
如果你能用手机管理 worktree,就不会再卡在“等我回到工位再说”。
本指南是一套以手机为操作中心、从容且可重复的 worktree 工作流。
快速定义:什么是 worktree(通俗版)
一个 Git 仓库通常只有一个工作目录(你检出的文件)。
worktree 让一个仓库拥有多个工作目录,这样你就能同时检出多个分支。
Git 官方文档将其描述为管理“附加到同一仓库的多个工作树”,让你可以同时检出多个分支。(来源:https://git-scm.com/docs/git-worktree)
实际上:
- 仓库的对象数据库是共享的
- 每个 worktree 都有自己检出的文件和 index/HEAD 状态
这就是为什么 worktree 比“把仓库克隆两次”轻量得多。
常见做法及其权衡
当热修复打断一项较大的改动时,常见选项是:
- stash:可行,但很容易忘记 stash 了什么、为什么
- 提交一个 WIP:可行,但会污染历史并招致错误
- 再克隆一次:可行,但慢,而且重复了大量内容
worktree 让你既保持主分支干净,又保持节奏。
可行的工作流
这套工作流在拥有仓库的电脑之上使用远程界面来进行日常 Git 操作。
Happier 是支持这种做法的选项之一。
每个 Happier 会话都绑定在你电脑上的一个文件夹,在手机上,会话会为该文件夹提供专属的 文件(Files)和 Git 标签页。所以一个 worktree 文件夹加上其中的一个会话就够了。
Git 写操作(提交、拉取、推送、切换分支)是实验性的,默认关闭。你可以在 设置(Settings)→ 功能(Features)→ 版本控制操作(Source control operations) 中开启(参见 Git 文档(英文))。查看状态和 diff 不需要开启它。
权衡:你的电脑仍需在线。
如果你第一次接触 Happier(它是什么,在哪里获取)
如果你之前没见过 Happier:它是一款开源配套应用(移动端/网页/桌面),让你把工作流留在信任的电脑上,再用手机管理。
开始设置:
- 如何在手机上使用 Happier
- GitHub: https://github.com/happier-dev/happier
- 安装/下载: https://github.com/happier-dev/happier#how-it-works
- Discord(社区与支持): https://discord.gg/W6Pb8KuHfg
防止出错的思路
在用手机操作 worktree 之前,先定两条规则:
-
一个 worktree = 一个目的。 如果热修复与当前工作无关,就应该有自己的 worktree。
-
手机上做小改动,大手术用键盘。 手机很适合审阅、轻量修改和推送范围很窄的修复。
分步操作:用手机管理 worktree
1) 在仓库文件夹中打开会话
打开一个在该仓库中运行的会话,或者新建一个会话,并选择电脑上的仓库文件夹作为工作目录。
2) 把 Git 标签页当作“安全检查界面”
在会话中:
- 打开 Git 标签页
- 从已更改的文件开始
这让你可以清晰地:
- 查看哪些有改动
- 有意识地提交
- 同步(拉取/推送)
如果你看到:
- Operation requires a clean working tree.(需要干净的工作区)
……把它当作护栏。
3) 创建一个新的 worktree(热修复)
创建 worktree 有两种思路:
- “我想为新分支建一个新目录”
- “我想为已有分支建一个新目录”
在原生 Git 中,基本就是:
git worktree add <path>(便捷地创建新分支)- 或
git worktree add <path> <branch>(已有分支)
(来源:https://git-scm.com/docs/git-worktree)
在 Happier 中,关键在于结果:
- 第二个工作目录,可以在其中启动自己的会话
- 不会打扰已经检出的内容
4) 手机上的修改保持范围窄
worktree 创建后,手机上的循环是:
- 打开在该 worktree 中运行的会话
- 用 文件 搜索目标文件
- 做最小的修改
- 保存(Save)
- 切换到 Git 标签页并审阅 diff
- 精确选择属于这次修复的文件(0.2.12 起支持),提交一个小改动
5) 推送热修复(然后停下)
热修复推送后,就停下。
worktree 的价值在于热修复不会扩展成第二个完整项目。
它保持范围很窄。
6) 清理 worktree(避免变得杂乱)
worktree 很强大,但会越积越多。
一条好规则:
- 如果分支已合并,就删除 worktree
- 如果是长期分支,就保留,但起个清楚的名字
在原生 Git 中,如果 worktree 被错误地删除,可以用 git worktree prune 清理残留的管理文件。(来源:https://git-scm.com/docs/git-worktree)
在以界面为主的工作流中,目标更简单:不要留下一堆被遗弃的工作目录。
worktree + 多个代理(为什么这开始变得重要)
worktree 早就存在,但当你并行运行多个代理或会话时,它会变得有用得多。
如果你在用 Claude Code、Codex 或 OpenCode,基本的多代理模式是这样的:
- 每个任务一个 worktree
- 每个 worktree 一个会话
这样你就获得了隔离:
- 代理之间不会互相踩文件
- diff 更容易审阅
- 提交保持范围窄
在 Happier 中,你不必把手机变成终端就能做到:
- 创建一个 worktree
- 在该 worktree 文件夹中启动一个新会话(Claude/Codex/OpenCode)
- 在审阅 diff、提交和历史的同一个应用里监控会话
这刻意不是“同时运行 10 个代理”。
而是:并行运行 2 到 3 个,并保持隔离,让审阅保持可控。
终端(可选)
当内嵌终端可用时,会话可以显示 终端(Terminal)标签页。根据功能矩阵(英文),它是实验性功能,需要已连接的守护进程和可访问的机器。
把终端当作应急出口,用于:
- 界面没有提供的那一条命令
- 快速核查
- 状态异常时清理 worktree
如果你发现自己什么都在终端里做,这是一个信号,说明你应该:
- 简化工作流,或者
- 等到有键盘的时候
常见问题(真实的 worktree 问题)
分支和 worktree 有什么区别?
分支是一个指针(一串提交的名字)。
worktree 是一个独立的工作目录,你可以在其中检出一个分支。
通常两者一起用:每个 worktree 一个分支。
为什么用 worktree 而不是 stash?
stash 很适合快速切换上下文。
当打断你的是真正的工作(热修复、审阅、跑测试),并且你想完全避免碰到当前改动时,worktree 很合适。
同一个分支能在两个 worktree 中检出吗?
默认情况下,Git 会阻止同一分支同时在两个 worktree 中检出。
这是一项安全功能。
(对于“只是跑测试”这类不需要分支的工作,你可以使用 detached HEAD 的 worktree。)
怎么给 worktree 起名,让以后的自己看得懂?
用能体现目的的名字:
hotfix-<ticket>review-<pr>release-<version>
worktree 常见的大问题是什么?
不在 Git 部分。
在人的部分:
- 忘了哪个 worktree 是“有未推送改动的那个”
- 留下做了一半的热修复 worktree
解决方法很简单:保持 worktree 范围窄,并及时清理。
什么时候不应该用手机操作 worktree?
当你要:
- 解决冲突
- 交互式 rebase
- 做大型重构
这些仍然更适合在键盘前完成。
“worktree is locked”是什么意思?
Git 允许你锁定一个 worktree,使其不会被自动 prune 或清理。
如果 worktree 位于不总是挂载的磁盘或位置上,这很有用。
“prune”做什么,什么时候需要?
如果 worktree 文件夹被错误删除(没有通过 git worktree remove),Git 可能会留下过期的元数据。
git worktree prune 会清理这些过期的管理文件。
如果你从不手动删除 worktree 文件夹,就很少需要它。
可以用 worktree 把长期分支分开吗(不只是热修复)?
可以,这是很好的用法。
例如:
- 在主 worktree 中保持
main干净 - 把
release/<version>放在专门的 worktree 中 - 把长期的重构放在它自己的 worktree 中
这能减少上下文切换,也更方便快速审阅。
worktree 之间会共享 node_modules 或构建产物吗?
不会自动共享。
每个 worktree 都是独立的目录,所以大多数工具会把它当作单独的项目文件夹。
如果你想共享缓存,通常由语言或工具层处理(pnpm store、Gradle 缓存等),而不是 Git。
worktree 文件夹应该放在哪里?
放在主仓库文件夹旁边,并起清楚的名字。
例如:
repo/(主 worktree)repo--hotfix-123/repo--release-1.2/
好的命名方案,是在手机屏幕上一眼就能看出你在看什么的方案。
可以用手机安全地删除 worktree 吗?
可以,但先遵守一条安全规则:
- 确保它没有未提交的改动
- 也没有你仍然在意的未推送提交
删除前快速看一眼“更改的文件”(Changed files),是很便宜的保险。
git worktree 和 git switch / git checkout 是一回事吗?
不是。
switch/checkout改变单个工作目录指向的分支。worktree add创建第二个工作目录,让你不必切走。
我应该用 worktree 代替分支吗?
不。worktree 是对分支的补充。
好的默认做法仍然是:
- 每个 worktree 一个分支
worktree 能和子模块一起用吗?
可以,但要小心:每个 worktree 都有自己的检出状态。
如果子模块是你工作流的一部分,手机上的修改要保持范围窄,更深的“子模块手术”留到键盘前做。