CCLearn

The worktree sweep is not what eats your work

Claude Code's worktree sweep skips any worktree holding changed files, untracked files, or unpushed commits, so the timer is not the risk: the exit prompt and git worktree remove --force delete the directory, its branch, and everything uncommitted. Commit before you leave.

circulating and false

This advice is common and does not hold. The official page saying otherwise is linked below.

What this costs you if it is wrong

The recovery half touches destructive git territory: `git worktree remove --force` discards uncommitted changes and untracked files with no prompt, so never run it to "clean up" a worktree you have not inspected with `git status` first. The tip's causal story is contradicted by current docs, so do not repeat "the sweep eats uncommitted work" as fact — cite the exit prompt instead. The habit itself costs one throwaway commit and is safe even if the whole incident was misattributed.

You have three sessions running in worktrees, you close the laptop on Friday, and on Monday one of them is a directory you never think about again. Nothing in git status on your main checkout mentions it. Weeks later the directory is gone, and the question is whether Claude Code took it or you did.

The circulating warning says the timer took it: worktrees are garbage-collected on cleanupPeriodDays, one user lost ten days of uncommitted work across 300+ files, so never leave anything in a worktree. The advice is good. The mechanism it blames is the one thing the docs explicitly rule out.

What the docs actually say about the sweep

The periodic sweep does exist, it does key off cleanupPeriodDays (default 30 days), and it does remove worktrees Claude Code created for subagents and background sessions. But the worktrees page lists, first among the cases where the sweep leaves a worktree alone: "The worktree still holds work: changed or untracked files, or unpushed commits."

So per the documented behavior, the exact state the warning tells you to fear — a worktree full of uncommitted edits — is the state that makes the sweep skip it. Uncommitted work is what saves the directory from the timer, not what exposes it.

The paths that really do delete a worktree

Reordering by what the docs describe rather than by what the warning claims:

PathWhen it firesWhat it takesPrompts first
Exit of an interactive worktree session, worktree cleanUnnamed session endsWorktree directory and its branchNo — automatic
Exit, worktree clean, named sessionNamed session endsSame, if you choose removeYes
Exit, worktree has changes or new commitsAny interactive session endsDirectory, branch, and everything in themYes — keep or remove
git worktree remove --forceYou run itUncommitted changes and untracked filesNo
Periodic sweep on cleanupPeriodDaysSubagent / background-session worktrees older than the limitOnly worktrees with no work in themNo
Exit of a -p non-interactive runNeverNothing — the worktree is left behind, lockedN/A

Read down that table and the dangerous keypress is at session exit, not on a timer. "Remove" at the exit prompt deletes the directory and the branch, which is what makes it worse than an ordinary rm: there is no ref left pointing at anything you committed.

The habit is still right, for a different reason

Commit inside a worktree before you leave it, even a wip commit you will squash. Not because the sweep is coming for you, but because:

  • A commit survives the exit prompt answered wrong at 2am. Uncommitted files do not.
  • A commit survives git worktree remove --force, which the docs hand you as the normal way to clear a worktree the sweep keeps.
  • A commit is the only thing git reflog and git fsck --no-reflogs --unreachable can recover after the branch ref is gone. Recovery advice for worktrees is entirely about commits; there is no recovery story for files that were never staged.
  • It flips the sweep's own rule in your favor: unpushed commits count as "work", so the timer keeps its hands off.

Naming the session helps too, and for a reason the docs make precise rather than vague: a clean worktree belonging to an unnamed session is removed automatically at exit, while a named session is prompted first. Naming does nothing for a dirty worktree — that always prompts — so the benefit is narrow and only covers the clean case.

What is unverified here, plainly

  • The incident. One GitHub report, closed as not planned, never reproduced, against a version now months old. Nobody has re-run it. The 300-file, ten-day figure is the reporter's, unaudited.
  • The causal claim. "The sweep deletes uncommitted work" is contradicted by the current worktrees page. It could still be true of the version that reporter ran; it is not true of what is documented today.
  • Whether the loss was the sweep at all. An exit prompt answered "remove", a --force, or the pre-v2.1.246 marker bug all produce an identical aftermath: a missing directory and no memory of which one did it.

What would settle it: create a worktree, leave uncommitted changes in it, backdate its record past cleanupPeriodDays, start a session to trigger the sweep, and see whether the directory survives. Until someone does that on a current build, treat the sweep as unproven and the exit prompt as the documented risk.

Do this before you close a worktree session

bash
git status --short          # inside the worktree
git add -A && git commit -m "wip"
git worktree list           # from the main checkout, weekly

If a worktree has already gone, look for the branch before you assume the work is lost: git branch -a sometimes still holds the ref, and git reflog plus git fsck --no-reflogs --unreachable can surface dangling commits. Every one of those recovers commits only. Files you never committed are not in the object store, and nothing on this list will find them.

Checkpoint

  1. Your worktree has uncommitted edits and is older than cleanupPeriodDays. Per the documented sweep rules, does the sweep remove it — and why?
    Show answer

    No — it leaves it alone. The worktrees page lists first among the cases where the sweep skips a worktree: "The worktree still holds work: changed or untracked files, or unpushed commits." Uncommitted edits are therefore what protect the directory from the timer, not what exposes it, and the circulating warning blames the one mechanism the docs rule out. Two hedges stay attached: documented behavior is a claim about the current version, and before v2.1.246 the sweep did not check for the marker Claude Code writes into worktrees it creates, so it could remove one you made yourself when an old background-session record pointed at it.

  2. Which single action, in the table above, deletes both the worktree directory and its branch without any prompt?
    Show answer

    Exiting an interactive worktree session when the worktree is clean and the session is unnamed. That row takes the directory and its branch automatically, no prompt — which is what makes it worse than an ordinary rm, since no ref is left pointing at anything you committed. Naming the session buys a prompt in exactly that clean case and nothing more; a dirty worktree always prompts. git worktree remove --force also runs without prompting, but you have to invoke it yourself and it takes uncommitted changes and untracked files, not the branch.

  3. You committed once in a worktree that has since vanished, and git branch -a shows nothing. What is your next command, and what would it not have found if you had never committed?
    Show answer

    git reflog, then git fsck --no-reflogs --unreachable to surface dangling commits. Both recover commits only. Had you never committed, neither would have found anything: files that were never staged never entered the object store, and no recovery path on that list reaches them. That gap is the entire argument for the throwaway wip commit before you leave a worktree.

Where this came from

What the docs actually say