Repository navigation
fix(remove): name trash staging dirs by worktree registration - #4361
Merged
Merged
Conversation
Removal renamed each worktree to `wt/trash/<basename>-<epoch-second>`. Worktrees that share a basename — Codex places every worktree at `~/.codex/worktrees/<id>/<repo>` — collided when `wt step prune` removed two of them in the same second: the second rename failed onto an existing directory, and prune's `SynchronousForNonCurrent` fallback ran `git worktree remove` in the foreground. The summary line then waited for that recursive delete (about 10s observed on a real prune), with no signal of why. The staging name now uses the worktree's registration id under `<common>/worktrees/`, which git keeps unique among a repository's worktrees. `ensure_holds_this_worktree` already resolves and verifies that git dir, so it now returns it. A failed rename logs its error at debug level instead of discarding it. The new prune test relies on the suite's pinned `epoch_now()`, which makes the collision deterministic under the old naming. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
worktrunk-bot
approved these changes
Oct 4, 2026
Log the rename error through inspect_err so the existing branch keeps its shape; the match form re-indented an untestable debug line into the diff. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
worktrunk-bot
approved these changes
Oct 4, 2026
This was referenced Oct 4, 2026
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A
wt step pruneprinted every per-item line quickly, then sat for about 10s before itsPruned …summary. Two of the pruned worktrees were Codex worktrees, which all live at~/.codex/worktrees/<id>/<repo>and so share the basenameMackup. Removal staged each worktree at.git/wt/trash/<basename>-<epoch-second>, so the two concurrent removals picked the same path in the same second. The second rename failed onto the existing directory, and prune's synchronous fallback rangit worktree removein the foreground; the summary waited for that recursive delete. The run's logs show it: nine worktrees got a detachedinternal/remove.log, the tenth (codex/promptfoo-followups) none.Staging names now use the worktree's registration id under
<common>/worktrees/, which git keeps unique among a repository's worktrees.ensure_holds_this_worktreealready resolves and verifies that git dir, so it now returns it. A failed rename also logs its error at debug level instead of discarding it.The collision predates #4337: v0.80.0 shows the same 3.4s stall on a two-worktree repro (50k ignored files each), which drops to 0.17s with this change. The new prune test relies on the suite's pinned
epoch_now(), which makes the collision deterministic under the old naming; it fails without the fix.