Skip to content

fix: keep worktree removal responsive - #2334

Closed
theMackabu wants to merge 3 commits into
herdrdev:masterfrom
theMackabu:fix/async-worktree-removal
Closed

fix: keep worktree removal responsive#2334
theMackabu wants to merge 3 commits into
herdrdev:masterfrom
theMackabu:fix/async-worktree-removal

Conversation

@theMackabu

Copy link
Copy Markdown

changes

  • dismiss the removal confirmation once the background operation starts
  • show an animated spinner on the affected sidebar workspace
  • reopen the confirmation dialog if removal fails

@kangal-bot kangal-bot added the ai-review Trigger automated AI reviews for pull requests admitted by the PR gate label Aug 4, 2026
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ca13b7c1-0960-44bd-a0a1-296e3e208437

📥 Commits

Reviewing files that changed from the base of the PR and between 991b9c1 and 422e592.

📒 Files selected for processing (1)
  • src/app/api/worktrees/deferred.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/app/api/worktrees/deferred.rs

📝 Walkthrough

Walkthrough

Worktree removal now runs in the background with spinner progress on workspace rows. Completion and failure handling preserve or restore the correct UI state. Tests cover spinner timing, removal lifecycle, workspace preservation, and rendering. Configuration documentation describes the updated behavior.

Changes

Background worktree removal

Layer / File(s) Summary
Removal spinner state and scheduling
src/app/state.rs, src/app/mod.rs, src/app/runtime.rs, src/app/input/mouse.rs
Removal state stores a spinner frame. Runtime scheduling advances active removals and clears the deadline when removal ends.
Asynchronous removal lifecycle
src/app/worktrees.rs, src/app/api/worktrees/deferred.rs, src/app/api/worktrees.rs
Accepted removals start the spinner and leave confirmation mode. Failures restore confirmation mode. Successful background removals preserve the current workspace and clear removal state.
Workspace-row progress rendering
src/ui/sidebar.rs
Collapsed and expanded workspace rows display the removal spinner and removing status. Rendering tests cover active removal progress.
Configuration documentation
docs/next/website/src/content/docs/configuration.mdx, docs/next/website/src/content/docs/ja/configuration.mdx, docs/next/website/src/content/docs/zh-cn/configuration.mdx
Documentation describes background removal and workspace-row progress while preserving safe-delete and branch behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant worktrees.rs
  participant deferred.rs
  participant runtime.rs
  participant sidebar.rs
  User->>worktrees.rs: request worktree removal
  worktrees.rs->>runtime.rs: start removal spinner
  worktrees.rs->>deferred.rs: submit deferred removal
  runtime.rs->>sidebar.rs: advance spinner frame
  deferred.rs->>worktrees.rs: report completion or failure
  worktrees.rs->>runtime.rs: stop removal spinner
  worktrees.rs->>sidebar.rs: render updated workspace state
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 54.55% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: keeping worktree removal responsive during background processing.
Description check ✅ Passed The description directly matches the changeset by covering confirmation dismissal, spinner feedback, and failure recovery.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Aug 5, 2026

Copy link
Copy Markdown

Greptile Summary

The PR moves worktree removal into a responsive background UI flow while retaining failure confirmation.

  • Dismisses the removal dialog after asynchronous work begins.
  • Animates removal status on the affected workspace and worktree group.
  • Reopens confirmation with force or error details when removal fails.
  • Preserves the user's current workspace and mode after successful background completion.
  • Documents background removal behavior in all supported configuration guides.

Confidence Score: 5/5

The PR appears safe to merge within the scope of this follow-up review.

No blocking failure remains in the eligible review scope.

Important Files Changed

Filename Overview
src/app/worktrees.rs Moves TUI removal into the background, manages completion state, and preserves workspace focus during successful removal.
src/app/runtime.rs Adds the worktree-removal spinner deadline and advances its animation through scheduled tasks.
src/app/api/worktrees/deferred.rs Integrates spinner cleanup and confirmation restoration with deferred API removal completion.
src/app/state.rs Adds the spinner frame to transient worktree-removal state.
src/ui/sidebar.rs Renders animated removal indicators and status text on affected workspace and group rows.
src/app/mod.rs Initializes the runtime-only spinner deadline.
src/app/api/worktrees.rs Extends deferred-removal tests to cover spinner cleanup and mode preservation.
src/app/input/mouse.rs Updates mouse interaction fixtures for the expanded worktree-removal state.
docs/next/website/src/content/docs/configuration.mdx Documents responsive background worktree removal in English.
docs/next/website/src/content/docs/ja/configuration.mdx Documents responsive background worktree removal in Japanese.
docs/next/website/src/content/docs/zh-cn/configuration.mdx Documents responsive background worktree removal in Simplified Chinese.

Sequence Diagram

sequenceDiagram
  participant User
  participant App
  participant Git as Background git
  participant Sidebar
  User->>App: Confirm worktree removal
  App->>Git: Start deferred removal
  App->>App: Dismiss confirmation
  App->>Sidebar: Animate affected workspace
  alt Removal succeeds
    Git-->>App: Success
    App->>Sidebar: Remove workspace and stop spinner
  else Removal fails
    Git-->>App: Error
    App->>App: Stop spinner and reopen confirmation
  end
Loading

Reviews (2): Last reviewed commit: "address coderabbit wet code nit" | Re-trigger Greptile

@theMackabu

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/app/api/worktrees/deferred.rs (1)

505-531: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consolidate the duplicated match-condition check.

Lines 512-522 and 523-528 both re-derive remove.workspace_id == result.workspace_id && remove.path == result.path separately: once to mutate removing/error/force_confirmation, and again immediately after to decide whether to stop the spinner and force the mode switch. Combine both checks into a single if let Some(remove) = &mut self.state.worktree_remove { if <condition> { ...mutate...; stop spinner; set mode; } } block so the two decisions can never drift apart if one condition is edited later without the other.

♻️ Proposed consolidation
-            if let Some(remove) = &mut self.state.worktree_remove {
-                if remove.workspace_id == result.workspace_id && remove.path == result.path {
-                    remove.removing = false;
-                    if code == "dirty_worktree_requires_force" && !remove.force_confirmation {
-                        remove.force_confirmation = true;
-                        remove.error = None;
-                    } else {
-                        remove.error = Some(message.clone());
-                    }
-                }
-            }
-            if self.state.worktree_remove.as_ref().is_some_and(|remove| {
-                remove.workspace_id == result.workspace_id && remove.path == result.path
-            }) {
-                self.stop_worktree_remove_spinner();
-                self.state.mode = crate::app::Mode::ConfirmRemoveWorktree;
-            }
+            let matches_current_remove = self.state.worktree_remove.as_ref().is_some_and(|remove| {
+                remove.workspace_id == result.workspace_id && remove.path == result.path
+            });
+            if matches_current_remove {
+                if let Some(remove) = &mut self.state.worktree_remove {
+                    remove.removing = false;
+                    if code == "dirty_worktree_requires_force" && !remove.force_confirmation {
+                        remove.force_confirmation = true;
+                        remove.error = None;
+                    } else {
+                        remove.error = Some(message.clone());
+                    }
+                }
+                self.stop_worktree_remove_spinner();
+                self.state.mode = crate::app::Mode::ConfirmRemoveWorktree;
+            }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bd89c319-e92a-4269-8574-b1030e4f7377

📥 Commits

Reviewing files that changed from the base of the PR and between 1f1e434 and 991b9c1.

📒 Files selected for processing (11)
  • docs/next/website/src/content/docs/configuration.mdx
  • docs/next/website/src/content/docs/ja/configuration.mdx
  • docs/next/website/src/content/docs/zh-cn/configuration.mdx
  • src/app/api/worktrees.rs
  • src/app/api/worktrees/deferred.rs
  • src/app/input/mouse.rs
  • src/app/mod.rs
  • src/app/runtime.rs
  • src/app/state.rs
  • src/app/worktrees.rs
  • src/ui/sidebar.rs

@ogulcancelik

Copy link
Copy Markdown
Collaborator

i don't have have a problem here. please open a discussion if it feels slow, or an issue if it's preventing you to use herdr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-review Trigger automated AI reviews for pull requests admitted by the PR gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants