焕 Kelvin Chen ~/nyc

← Notes · 随想 · 指南

Claude Code worktrees — when to work in an isolated copy

Claude Code 工作树 · 什么时候让它在副本里干活

Claude Code has a worktree toggle — work in an isolated copy of the repo, or not. It confused me for a while, so here is the plain version: what ON and OFF actually mean, when I use each, the one trap that bit me, and how to clean up afterwards.

Claude Code 里有一个「工作树」开关 —— 要不要在仓库的一份隔离副本里干活。这个开关我搞混过好几次,所以写下来:开和关分别是什么意思、我自己什么时候用哪个、最容易踩的一个坑,以及用完之后怎么清理。

00 · 一句话开着是副本,关着是真身the one-line version

开启(ON)= Claude 在你仓库的一份临时副本里干活,你真实的文件夹一动不动;做完之后,由你决定要不要把结果合并回来。关闭(OFF)= Claude 直接改你真实的文件夹。

Worktree ON means Claude works in a throwaway copy of your repo and leaves your real folder untouched; you merge the good result back when it's done. Worktree OFF means Claude edits your real folder directly.

厨房比喻 · the kitchen analogy

关闭 = 在你自己家的厨房做饭。快,但搞乱了,乱的就是你家。

开启 = 在隔壁一模一样的出租厨房做饭。你家始终干净;菜做好了端过来,做砸了直接走人。

OFF is Claude cooking in your actual kitchen — fast, but a mess is your mess. ON is Claude cooking in an identical rented kitchen next door — your kitchen stays clean; carry the dish over when it's good, walk away if it's a disaster.

它不是什么魔法,背后就是 git 自带的 git worktree:同一个仓库的第二份 checkout,在自己的分支上,放在一个隐藏的 .claude/worktrees/… 文件夹里。每个开着这个开关的会话都有自己的一份副本,所以好几个会话可以同时跑,互不踩脚。

It isn't magic — it's git's built-in git worktree: a second checkout of the same repo, on its own branch, living in a hidden .claude/worktrees/… folder. Each session with the toggle ON gets its own copy, so several can run at once without stepping on each other.

01 · 两种模式开和关,各自换来什么what each mode buys you

worktree ON · 开启

隔离副本 · 隔壁的出租厨房

Isolated copy — the rented kitchen next door

  • 真实文件是安全的。做到一半的改动碰不到你真正的文件。

    Half-finished edits never touch your working files.

  • 可以并行。每个会话一份副本,同时跑几件事也不会撞车。

    Each session gets its own copy, so parallel tasks don't collide.

  • 不满意就丢掉。把副本删了,仓库还是原来的样子,没有什么要收拾的。

    Don't like it? Discard the worktree — the real repo is untouched.

  • 合并由你决定。改动停在一个分支上,你看过之后才算数。

    The work sits on a branch until you review it and merge it in.

worktree OFF · 关闭

真实文件夹 · 自己家的厨房

Your real folder — your own kitchen

  • 改了就生效。没有合并这一步,适合想马上用上的小改动。

    Edits land immediately, no merge step.

  • 路径是真的。跑在你的工具和脚本预期的那个绝对路径上。

    It runs at the real absolute path your tools expect.

  • 不会堆一堆副本。每开一次工作树,就多一份磁盘占用和一个之后要清理的分支。

    No worktrees and dangling branches piling up to clean later.

  • 不在 git 里的事情,副本没意义。只是聊天,或者改的是 git 管不到的文件,隔离不了什么。

    Just talking, or editing files outside git? A copy adds nothing.

02 · 最容易踩的坑绝对路径the trap — absolute paths

假通过 · the false pass

工作树在另一个路径下(.claude/worktrees/…)。凡是必须在真实仓库路径上运行的东西 —— 定时运行的脚本、写死了路径的生成脚本、往某个固定文件夹写数据的任务 —— 要么关掉工作树,要么做完马上合并。

在临时路径里测试,很可能「看起来通过了」;等工作树被删掉,或者后台任务从真实路径去跑,才发现是坏的。

A worktree lives at a different path. Anything that has to run against the real repo path — a scheduled script, a generator with hardcoded paths, a job that writes into a fixed folder — should run with the toggle OFF, or be merged right away. Testing inside the temporary path can give a false pass that only breaks once the worktree is gone, or once the background job runs from the real location.

03 · 何时用哪个我自己的判断方法when to use which — here's what I do

开启,当 · turn it ON when

  • 一个自成一体的功能、分析或文档,你打算先看再留。

    A self-contained feature, analysis or doc you'll review before keeping.

  • 你想同时跑好几件事。

    You want several tasks running at once.

  • 任何实验性的、可能会整个扔掉的尝试。

    Anything experimental you might throw away.

关闭,当 · turn it OFF when

  • 一个快速、有把握的小改动,你想让它现在就在真实文件夹里生效。

    A quick, trusted edit you want live in the real folder now.

  • 这件事依赖真实的绝对路径(定时任务、部署脚本、固定的数据文件夹)。

    The work depends on the real absolute path — scheduled jobs, deploy scripts, a fixed data folder.

  • 你在测试一个后台任务也会跑的东西 —— 那就测它真正会用到的那个文件。

    You're testing something a background job also runs — test the same file it will.

我的默认 · my default

我平时让 Claude 做的,大多是「写个小工具 / 做个分析 / 起草一篇东西」—— 这些都属于开启的范围。一旦这件事需要在真实路径上运行,我就关掉,或者做完马上合并。

Most of what I ask for is "build a small tool / run an analysis / draft a write-up" — that's ON territory. The moment the work has to run at the real path, I flip it OFF, or merge right away.

04 · 几个例子放到具体的事情上worked examples

worktree ON ✓ · 典型的开启

一篇调研 write-up

A research write-up

自成一体,不依赖任何路径。在副本里起草,看一遍,再合并。教科书式的开启。

Self-contained, no path dependencies — draft in the copy, review, merge. Textbook ON.

ON, then merge · 开启,但要记得合并

改一个定时任务会读的说明文件

Editing an instruction file that a scheduled task reads

在副本里起草没问题。但定时任务是从真实仓库路径读这个文件的,所以最终版本必须落到真实文件夹里。合并它,不要让它困在工作树里。

Fine to draft ON — but the scheduled job reads the file from the real repo path, so the final version has to land in the real folder. Merge it; don't leave it stranded in the worktree.

lean OFF · 倾向关闭

改一个写死路径、由后台任务执行的脚本

Changing a script with hardcoded paths that a background job runs

这类脚本把路径写死了,而且是在真实位置被后台任务执行的。在临时工作树路径里验证,可能会假通过。要么关掉工作树,要么马上合并,然后在真实路径上再验证一次。

These hardcode paths and get executed by background jobs at the real location. Validating them inside a temporary worktree path can falsely pass. Run OFF, or merge immediately and verify again at the real path.

housekeeping · 清理的现实

工作树会越积越多

Worktrees accumulate

开启的工作树会一直留着 —— 我有过两周前的还挂在那里。隔一段时间就看一眼,把没用的删掉。但删之前先检查有没有没提交的改动:我有一个工作树里放着一个没备份的小原型,要是闭着眼睛删,就没了。

ON worktrees stick around — I've found ones from two weeks back still hanging there. Clear them out now and then, but check for uncommitted work first: one of mine held a small prototype that wasn't backed up anywhere else, and a blind delete would have erased it.

05 · 清理速查四条命令housekeeping cheat-sheet

在仓库根目录下运行(例如 ~/Projects/my-app)。<path> 换成 git worktree list 列出来的那个路径。

Run from the repo root (say, ~/Projects/my-app). Replace <path> with a path from git worktree list.

# 1 · 查看全部 · see all worktrees
git worktree list

# 2 · 查有没有没保存的改动 · check one for unsaved work
#     (no output = clean)
git -C <path> status --porcelain

# 3 · 删除一个已经用完的 · remove a finished one
git worktree remove <path>

# 4 · 清理失效的记录 · prune stale entries
git worktree prune

删掉的是文件夹,不是分支 · the branch survives

工作树删掉之后,它的分支还在 —— 只要改动已经提交了,删文件夹不等于删工作。但没提交的改动和没被 git 跟踪的文件,会跟着文件夹一起没掉。所以永远先跑第 2 条。

A worktree's branch survives removal — deleting the worktree folder isn't deleting the work, as long as it was committed. Uncommitted edits and untracked files are lost with the folder, so always run step 2 first.

···

aboutAbout this noteand what it isn't

This started as a private cheat-sheet I kept for myself after mixing up the two modes a few times. I've cleaned it up and swapped my own projects for generic examples. It describes how I use the toggle on side projects; it isn't a complete reference for Claude Code or for git worktree.

这一份原本是我给自己写的小抄,因为开和关我搞混过几次。整理之后,把我自己项目里的例子换成了通用的例子。它讲的是我在个人项目里怎么用这个开关,不是 Claude Code 或 git worktree 的完整说明。

Not official documentation. Written by a user, not by Anthropic. The toggle's exact wording and where it sits in the app may differ from what's described here, and may change over time — the official Claude Code docs are the source of truth for the product. The git commands are standard git worktree; read what a command will remove before you run it.