工具大全
开发者工具作者:Coocon2026年9月13日4 次阅读约 6 分钟阅读

上周教你手写 git worktree,这周发现有人做成了一条命令:worktrunk 实测

上一篇讲 git worktree,结尾留了个尾巴:新开的目录是一份干净源码,node_modules 得再装一遍。我给的解法是「留一个常驻目录别删」,或者换 pnpm。发出去第二天就看到 worktrunk 上了热榜:一个专门管 worktree 的命令行工具,7.4k 星,Rust 写的,作者 Max Sixty(也是 PRQL 的作者)。

它的卖点一句话:让 worktree 像分支一样好用。原生 git 开一个 worktree 要把分支名打三遍(git worktree add -b feat ../repo.feat && cd ../repo.feat),它只要 wt switch -c feat

好用的包装很多,我更关心两件事:它到底省掉了哪几步,以及那个 node_modules 的尾巴它怎么收。于是在我自己的项目里跑了一遍,仓库 1.9 GB 的 node_modules,APFS 文件系统,worktrunk 版本 0.77.0。

安装:多一步「shell 集成」,原因值得知道

brew install worktrunk && wt config shell install

第二段命令很多人会跳过,然后发现 wt switch 不切目录。原因是一个 Unix 常识:子进程改不了父进程的工作目录wt 是个二进制,它自己 cd 了,你的 shell 还在原地。所以它要在你的 .zshrc 里注册一个同名 shell 函数,包住真正的二进制:二进制把目标路径写进一个临时文件,函数读出来再 builtin cd

我没装集成直接跑,它会明确告诉你目录没切,并给出路径。命令本身照常执行。如果你只在脚本或 CI 里用,可以不装。

建、列、删:确实是一条命令

在我的仓库里开一个新分支的 worktree:

$ wt switch --create wt-trial
✓ Created branch wt-trial from main and worktree @ ~/4khz/magictools.wt-trial

0.65 秒。目录放在仓库旁边,命名是 仓库名.分支名。分支名只打了一次。路径规则是个模板,可以改成放在 .worktrees/ 里或集中到 ~/worktrees/ 下,在配置文件里改一行。

wt list 是我觉得比原生好最多的地方。原生 git worktree list 只给路径和提交号,这个给状态:

  Branch    Status  HEAD±  mainmain…±  Remote⇅  Path                    Commit   Age  Message
@ main          ^|                            |     .                       4f02fb1  16m  chore: bump 1.4.230
+ wt-trial      _                                   ../magictools.wt-trial  4f02fb1  16m  chore: bump 1.4.230

@ 是当前所在,HEAD± 是未提交改动的行数,main↕ 是领先落后主分支几个提交,Remote⇅ 是有没有没推的。开着五六个目录时,一眼能看出哪个该合、哪个该删。

删除:

$ wt remove wt-trial
✓ Removed wt-trial worktree & branch (same commit as main, _) (57,506 files · 1.8 GiB)

原生要两步:git worktree removegit branch -d。它一步做完,而且只在分支已合并时才删分支,没合并的会拒绝。目录里有未提交文件也会拒绝,我故意留了个 dirty.txt,它列出文件名并停住,要加 --force 才删。这个保护和原生一致。

到这里的结论:建、列、删三件事,它确实各省了一到两步,list 的信息量是实打实的提升。但这三件事原生也就是四条命令,上一篇讲过了。真正让我决定装它的是下面这个。

node_modules 的尾巴:3 秒,不占磁盘

上一篇的问题是:新目录没有 node_modules,要么重装,要么留个常驻目录。worktrunk 的答案是 wt step copy-ignored:把主目录里被 .gitignore 忽略的文件拷到新目录。

关键在「拷」的方式。在 APFS(macOS)、btrfs 和 XFS 上,它用的是文件系统级克隆(reflink),相当于 cp -c:新文件和旧文件共享磁盘块,哪边写了才分家。

我先看它打算拷什么:

$ wt step copy-ignored --to wt-trial --dry-run
○ Would copy 408 entries:
  .DS_Store (file)
  .env (file)
  .next (dir)
  .secrets (dir)
  ...

停一下。 默认行为是拷所有被忽略的文件,我的仓库里 408 条,包括 .env.secrets/。对我这种单人仓库问题不大,但如果你的 worktree 是给 AI Agent 用的,或者目录会被同步到别处,这就是把密钥复制了一份。

限制范围要建一个 .worktreeinclude 文件,语法和 .gitignore 一样,只有同时被忽略且在这个文件里的才拷:

# .worktreeinclude
node_modules/

再跑一次:

$ time wt step copy-ignored --to wt-trial
✓ Copied 56233 files · 1.7 GiB (reflinked, no extra disk)
wt step copy-ignored  0.11s user 8.03s system 257% cpu 3.163 total

3.2 秒。df 前后的可用空间都是 184 GiB,一字节没多占。du -sh 看新目录的 node_modules 是 1.9 GB,那是逻辑大小,物理上和主目录共用。

然后在新目录里跑了 npm run typecheck,8 秒通过,和主目录一样。依赖是可用的,不是个空壳。

这个能力不是 worktrunk 独有的,你自己 cp -Rc node_modules ../repo.feat/ 也能做到,APFS 的克隆是系统自带的。它的价值是把这件事变成默认动作:在项目配置里加一个 post-start 钩子,每次 wt switch -c 建完目录自动在后台拷,你 cd 过去的时候依赖已经在了。

有两个限制要知道。一是 reflink 按文件计,时间随文件数线性涨,我 5.6 万个文件 3 秒,Rust 项目的 target/ 大文件少反而更快。二是 ext4 和 NTFS 没有这个能力,它会退化成真拷贝,输出里会写 (full copy) 而不是 (reflinked, no extra disk),看清楚再决定要不要拷。

wt merge:一条命令做完,但我不会开

它还有个 wt merge:把当前分支 squash、rebase 到主分支、快进合并、删目录删分支,一条命令。我在一个临时仓库里试了:

$ wt merge main --no-commit -y
◎ Merging 2 commits to main @ 9d9bc96 (no commit/squash/rebase needed)
  * 9d9bc96 feat: more
  * dee1fcb feat: change a, add b
✓ Merged to main (2 commits, 2 files, +3)
◎ Removing feat worktree & branch in background

跑得很干净。但我不会在团队仓库里用它,两个原因:

默认 squash。 它会把分支上的多个提交压成一个再合。这是作者的工作流偏好,有的团队要保留提交历史,得记住加 --no-squash

它是本地合并。 快进的是你本机的 main,合完还是要 push。走 PR 评审的团队,主分支根本不该在本地动。这个命令的场景是「一个人开一堆 Agent 各干各的,干完自己收」,不是多人协作。

--no-commit 那个参数也说明一件事:它默认会先帮你提交,提交信息是调 LLM 生成的,配置里推荐的命令是拿 Claude Haiku 跑。没配 LLM 就得关掉。我不想让一个 worktree 工具替我决定提交信息,所以一直关着。

它为谁而生

README 第一段说得很直白:为并行跑 AI Agent 设计。Claude Code 和 Codex 现在能自主干几十分钟,一个人开 5 到 10 个并行任务成了常态,每个任务要一个独立目录,这时候原生 worktree 的每一步多打几个字都会被放大十倍。

所以它有 wt switch -c -x claude feat:建目录、切过去、启动 Claude Code,一条命令。也有给每个 worktree 算一个独立端口的模板函数,避免多个 dev server 抢 3000。这些在你一次只干一件事的时候没用,在开五个 Agent 的时候是刚需。

如果你还没到那个用法,我的建议是:装它,只用 switch、list、remove 三个命令,再配上 copy-ignored 的钩子。这四件事覆盖了上一篇的所有场景,还把 node_modules 的尾巴收了。merge 和 LLM 提交先别碰。

该注意的

项目 2025 年 10 月才建,最近两周发了三个版本(0.75 到 0.77),累计 619 个 issue、44 个还开着。作者在 README 里自己说「请把任何摩擦都告诉我」。这是个在快速迭代的工具,命令和配置格式还在变,wt config update 这个子命令的存在本身就说明配置项已经改过。

我本机现在留着它。下次线上告急,动作从上一篇的三步变成:wt switch -c hotfix,修,wt remove。中间那步 npm install,没了。

今天就能做的事

brew install worktrunk && wt config shell install

# 在你的项目根目录
printf 'node_modules/\n' > .worktreeinclude
mkdir -p .config && cat > .config/wt.toml <<'EOF'
[post-start]
copy = "wt step copy-ignored"
EOF

然后 wt switch -c 随便一个名字,cd 过去看看 node_modules 在不在。在的话,看一眼 df,磁盘应该没少。

你的项目 node_modules 多大?评论区报个数,我猜超过 1 GB 的不少。

相关文章

改到一半要修线上 bug?别 git stash,用 git worktree 再开一个目录

写到一半被叫去修线上 bug,大多数人的肌肉记忆是 git stash → 切分支 → 修完 → 切回来 → stash pop。这条路每一步都有坑:stash 不带未跟踪文件、pop 会冲突、忘掉的 stash 堆成坟场。git worktree 让同一个仓库同时有两个目录、两个分支,修 bug 在另一个目录里做,主目录一个字节都不动。本文讲清 worktree 的原理、四条常用命令、和 stash 的适用边界,以及 node_modules 怎么办。

工作流git+4
developer2026年9月12日5 min
15

GitHub 宕机 7 个半小时那天,Cursor 发布了自己的代码托管平台

8 月 17 日 GitHub 经历了 7 小时 35 分的 critical 级事故——这是它两个月内的第 9 次 critical。同一天,Cursor 发布代码托管平台 Origin。一边是耐心耗尽的 Hacker News 认真讨论搬家,一边是带着 SpaceX 600 亿美元资本入场的挑战者。护城河开始松动了吗?我们把两件事的数据都核了一遍。

开发者工具github+4
developer2026年8月18日6 min
252

Cloudflare 钱包(Wallets)是什么、怎么注册?cloudflare.pay 抢注与使用全指南

Cloudflare 钱包(Cloudflare Wallets)是给 AI Agent 用的身份 + 稳定币钱包,目前唯一开放的功能是在 cloudflare.pay 免费抢注专属 handle。本文给出注册抢注的完整步骤、命名与审核规则、常见问题解答(多久能用、有什么用、能否绑定 ChatGPT、国内能不能用),以及 Account Wallet / Virtual Wallet / x402 的机制拆解。

cloudflareai-agent+5
ai-tutorials2026年8月5日8 min
1188

Claude Code Plan Mode 实战:先规划后动手,把返工率打下来

Plan Mode 是 Claude Code 的只读规划模式:先调研代码库、产出实施方案,经你批准后才动手改代码。本文讲清怎么进入 Plan Mode(Shift+Tab 循环切换)、它到底拦住了什么、什么任务该用什么任务不该用,以及让规划真正提质量的四个技巧。

claude-codeplan-mode+4
claude2026年7月28日3 min
256