You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
pstack: worktree-cleanup treats untracked and ignored files as disposable (--force, rm -rf) #449
The worktree-cleanup playbook and scripts/worktree-audit.sh (pinned at 12d587d) treat untracked and ignored files in a worktree as disposable.
scripts/worktree-audit.sh classifies untracked files as "disposable untracked scratch" (line 44) and counts only tracked edits as WIP.
playbooks/worktree-cleanup.md step 4 pauses only on tracked uncommitted edits (wip:N). Step 5 then runs git worktree remove --force <path>, and when the directory survives on ignored files, rm -rf followed by git worktree prune.
Untracked and ignored files are often the most valuable thing in an agent worktree: run artifacts, evidence directories, local graphs and indexes, .env files, scratch notes. None of these are recoverable from the branch. --force overrides exactly the refusal Git gives to protect them.
Expected: untracked and ignored files count as irreversible loss, like tracked WIP. The playbook pauses on them (or lists them for a decision) and never falls back to --force or rm -rf. A plain git worktree remove that refuses is the correct stop.
Hey, thanks for the report. I reproduced it on a synthetic repo, and it’s worse than described in one way.
With a worktree that has one untracked file plus an ignored build/ and run.log, the current worktree-audit.sh reports scratch:1 and puts it in the review bucket. Ignored files aren’t even detected because git status runs without --ignored. The playbook then treats that as safe to remove with --force. PR #459 fixes both issues. With it, the same worktree shows up as wip:3 and lands in hold-wip, and the playbook no longer falls back to --force, rm -rf, or prune.
One correction to the expected behavior in the issue. A plain git worktree remove is not a sufficient stop. Git only refuses when there are untracked or modified files. A worktree that contains only ignored files gets deleted silently even without --force. I verified this. That’s why #459’s explicit status --untracked-files=all --ignored=matching check before removal is the right guard, instead of relying on Git to refuse.
I reviewed #459 and flagged it to the pstack maintainer for merge. Until it lands, your own retirement procedure is the right call.
Activity
deanrie commentedon Oct 3, 2026
Hey, thanks for the report. I reproduced it on a synthetic repo, and it’s worse than described in one way.
With a worktree that has one untracked file plus an ignored
build/andrun.log, the currentworktree-audit.shreportsscratch:1and puts it in thereviewbucket. Ignored files aren’t even detected becausegit statusruns without--ignored. The playbook then treats that as safe to remove with--force. PR #459 fixes both issues. With it, the same worktree shows up aswip:3and lands inhold-wip, and the playbook no longer falls back to--force,rm -rf, orprune.One correction to the expected behavior in the issue. A plain
git worktree removeis not a sufficient stop. Git only refuses when there are untracked or modified files. A worktree that contains only ignored files gets deleted silently even without--force. I verified this. That’s why #459’s explicitstatus --untracked-files=all --ignored=matchingcheck before removal is the right guard, instead of relying on Git to refuse.I reviewed #459 and flagged it to the pstack maintainer for merge. Until it lands, your own retirement procedure is the right call.