Skip to content

feat(remove): instant worktree removal via move-then-delete#773

Open
max-sixty wants to merge 7 commits intomainfrom
remove-speed
Open

feat(remove): instant worktree removal via move-then-delete#773
max-sixty wants to merge 7 commits intomainfrom
remove-speed

Conversation

@max-sixty
Copy link
Owner

Summary

  • Make background wt remove instant by renaming the worktree to a staging path before spawning the background process
  • Eliminates the 1-second sleep and makes the worktree path unavailable immediately
  • Falls back to legacy git worktree remove if rename fails (cross-filesystem, permissions, Windows file locking)

How it works

  1. Rename worktree to staging path (<path>.wt-removing-<timestamp>) — instant on same filesystem
  2. Prune git metadata synchronously via git worktree prune — fast, no recursive file I/O
  3. Background: rm -rf the staged directory + branch deletion

Additional fixes

  • Show hooks_run_at path when cwd becomes invalid after rename
  • Use -- in rm/git commands to prevent option parsing for paths starting with -

Test plan

  • test_remove_background_path_gone_immediately — worktree path gone immediately
  • test_remove_background_git_metadata_pruned — git metadata pruned immediately
  • test_remove_background_deletes_merged_branch — branch deletion works with staged removal
  • test_remove_worktree_with_special_path_chars — paths with special chars handled correctly
  • All 90 existing remove tests pass
  • Pre-commit lints pass

🤖 Generated with Claude Code

max-sixty and others added 3 commits January 20, 2026 18:24
Make background removal instant by renaming the worktree to a staging
path before spawning the background process. This eliminates the
1-second sleep and makes the worktree path unavailable immediately.

The new approach:
1. Rename worktree to staging path (instant, same filesystem)
2. Prune git metadata synchronously via `git worktree prune`
3. Background: `rm -rf` the staged directory + branch deletion

Falls back to legacy `git worktree remove` if rename fails (cross-
filesystem, permissions, Windows file locking).

Also fixes:
- Show hooks_run_at path when cwd becomes invalid after rename
- Use `--` in rm/git commands to prevent option parsing for paths
  starting with `-`

Co-Authored-By: Claude <noreply@anthropic.com>
- Update generate_removing_path() to use get_now() utility
  for deterministic timestamps in tests (respects WT_TEST_EPOCH)
- Add test_remove_background_fallback_on_rename_failure test that
  exercises the fallback path when std::fs::rename() fails
- The test blocks the rename by creating a file at the expected
  staged path, forcing fallback to legacy git worktree remove

Co-Authored-By: Claude <noreply@anthropic.com>
@max-sixty max-sixty added the feedback-requested Looking for user feedback on this feature label Jan 22, 2026
max-sixty and others added 4 commits January 22, 2026 00:21
Resolved conflicts in:
- src/commands/process.rs: Combined imports (FromStr, IntoEnumIterator, HookType)
  and merged both test sets (generate_removing_path, build_remove_command_staged
  from HEAD; hook_log tests from main)
- src/output/handlers.rs: Combined imports (HookLog, InternalOp from main;
  build_remove_command_staged, generate_removing_path from HEAD)

Co-Authored-By: Claude <noreply@anthropic.com>
Resolve conflict in src/output/handlers.rs: keep both the new instant
removal functions (build_remove_command_staged, generate_removing_path)
from remove-speed and the refactored hooks module imports from main.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feedback-requested Looking for user feedback on this feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant