Skip to content

fix(daemon): remove worktrees off the daemon loop - #26

Merged
marcrdgz merged 1 commit into
mainfrom
fix/async-worktree-removal
Oct 21, 2026
Merged

marcrdgz merged 1 commit into
mainfrom
fix/async-worktree-removal

Conversation

@marcrdgz

Copy link
Copy Markdown
Owner

git worktree remove deletes the whole checkout, including ignored build output (target/, node_modules/). That can take a minute, and until now it ran on the daemon loop, so every client froze for the duration.

Changes

  • Split removal into three phases (new daemon/app/worktree_removal.rs):
    • On the loop: the quick checks and session teardown (begin_worktree_removal). These find the repo root, refuse the main worktree, check the tree is clean and close the owning session. If any of them fails, the session is left untouched.
    • On a worker thread: waiting for the PTY cleanup workers, re-checking the tree is clean, then the git worktree remove and branch cleanup (WorktreeRemoval::run). This part never touches App.
    • Back on the loop: finish_worktree_removal applies the result. On failure it reopens the closed session, as the old synchronous path did.
  • Deferred reply. Command::WorktreeRemove now gets its Reply when the worker finishes, delivered through finish_worktree_removals on each loop iteration. Other commands keep being answered in the meantime.
  • One removal per path. In-flight removals are keyed by canonical path, and a second request for the same path is rejected with "already being removed".
  • Shutdown and update re-exec. Running removals are joined before the daemon stops or re-execs, so a deletion is never cut short. On re-exec, a session reopened after a failed removal is included in the resume state.
  • Removing the last session. When the removal closes the last session, the daemon is about to quit. In that case the removal runs inline and the reply is sent before the daemon exits.

Tests

  • New: worktree_removal_does_not_block_the_daemon_loop. It checks that a command sent right after WorktreeRemove is answered before the removal finishes.
  • Gate is green: cargo build, cargo test and cargo clippy on the whole workspace.

Risk

  • The reply to WorktreeRemove now arrives later, after other events. Any client that expected the reply right away still gets it, just later. The wire protocol is unchanged.
  • Daemon shutdown and update re-exec can now wait for a removal that is still running.

@marcrdgz marcrdgz self-assigned this Oct 21, 2026
@marcrdgz
marcrdgz merged commit 811ed2b into main Oct 21, 2026
2 checks passed
@marcrdgz
marcrdgz deleted the fix/async-worktree-removal branch October 21, 2026 20:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant