我坚信Git工作树是Git中最被低估的功能之一。多年来我一直忽视它们,因为我不理解它们,也不知道如何将其适配到我的工作流程中。
但当我开始使用LLM编码工具进行更多并行工作时,情况发生了变化。能够同时在多个分支上工作是一个游戏规则的改变者。
如果没有Git工作树,在同一仓库中同时处理多个分支是一件痛苦的事情。要么采用串行方法:暂存你的更改,切换上下文,并祈祷你没有破坏任何东西。或者更糟的是,用“WIP”消息提交半成品(说的就是你,过去的我)。或者,你可以拥有同一仓库的多个克隆副本,但这难以管理并且会占用大量磁盘空间。
Git工作树解决了这个问题。它们允许你在不同的目录中同时检出多个分支,这些目录都共享同一个Git数据库(即.git目录)。对我来说,这意味着我可以在一个终端中处理一个功能,在另一个终端中审查PR,让Claude Code在另一个终端中处理另一个功能,并且所有这些都共享相同的Git历史记录。
但问题是:手动创建工作树很繁琐。你需要记住把它们放在哪里、如何命名,以及之后清理它们。此外,默认情况下,除非指定不同的目录,否则Git工作树会在仓库的根目录中创建。
我想要更简单的东西。我想要一个能在任何仓库中工作的工具。无需设置,无需配置文件,只有合理的默认值。
介绍 tree-me
我构建了tree-me,这是一个围绕Git原生工作树命令的最小化包装器。它在让Git处理所有复杂性的同时,增加了组织性的约定。
取代这种繁琐操作:
|
|
你只需这样做:
|
|
工作原理
tree-me使用类似Git的子命令并遵循约定,让你无需思考:
- 自动从Git远程仓库检测仓库名称
- 自动检测默认分支(检查origin/HEAD,回退到main)
- 按仓库组织:
$WORKTREE_ROOT/<repo-name>/<branch-name> - 将所有的验证、错误处理和边缘情况委托给Git处理
- PR支持:使用Git的原生PR引用获取GitHub PR(需要gh CLI)
- 自动切换目录:创建后自动切换到工作树目录
- 标签补全:在bash/zsh中补全命令和分支名称
命令
|
|
示例
|
|
约定
tree-me是Git原生命令的最小化包装器。适用于任何仓库、任何语言、任何设置。唯一的约定是工作树的存放位置和命名方式。
希望工作树放在不同的位置?设置WORKTREE_ROOT。需要从develop而不是main创建分支?将其作为参数传递:tree-me create my-feature develop。有约定,也有变通方案。
设置
要启用自动切换目录和标签补全,请将以下内容添加到你的~/.bashrc或~/.zshrc:
|
|
这使得tree-me create、tree-me checkout和tree-me pr命令自动切换到工作树目录。同时还能启用命令和分支名称的标签补全(试试tree-me rm <TAB>)。
可以在 github.com/haacked/dotfiles/blob/main/bin/tree-me 查看完整实现。
PR工作流
这是它大放异彩的地方。当你正深入处理某个功能时,有人请你审查一个PR:
|
|
当你审查完成:
|
|
完成。清理干净。不会意外地将审查更改提交到你的功能分支。
注意:tree-me使用gh CLI来获取PR。如果你没有安装它,可以使用
brew install gh安装。
安装
下载tree-me并将其放在你的PATH环境变量中的某个位置:
|
|
然后启用自动切换目录和标签补全(参见上面的设置部分)。
就这些了。除了Git、bash和可选的用于PR检出的gh CLI外,没有其他依赖。
为什么构建这个工具
我每天处理多个仓库——PostHog、我的博客、各种开源项目。我厌倦了记住特定于项目的工作树脚本,并寻找上周创建的工作树。
哲学是:不要重新实现Git已经做得很好的事情。只添加所需的最小约定。
Git已经完美地处理了工作树。我只需要有组织的路径、合理的默认值以及跨所有项目的一致接口。
目录结构
一切都根据仓库名称和分支名称有条理地组织:
|
|
例如:
|
|
一目了然,你就知道一切在哪里。
它不做什么
tree-me不复制环境文件、安装依赖项或设置项目特定工具。这是故意的。这些问题属于你项目的设置脚本,而不是一个通用的Git工具。
想要自动化环境设置?在你的仓库中添加一个在检出后运行的脚本。想要复制.env文件?把它放在你项目的入门文档中。tree-me只处理Git工作树的仪式性操作。
试试看
如果你经常处理多个分支,请尝试使用工作树。如果你处理多个仓库,请尝试使用tree-me。如果你讨厌它,至少你了解了Git工作树(这可能比脚本本身更有价值)。
可以在 github.com/haacked/dotfiles/blob/main/bin/tree-me 找到tree-me。它是MIT许可的——可以复制、修改、改进它。