Add an opt-in Clean action to the Worktrees inventory#8
Conversation
9b1d54c to
4758c00
Compare
The Worktrees modal was read-only: it could only copy a `git worktree remove` command for the user to run. Add a `Clean` button (Tauri-only) that runs it, behind a dry-run + confirmation, so disk hygiene happens in one place instead of bouncing to a terminal. - Backend (src-tauri/src/worktrees.rs): remove_worktree/prune_worktrees -> CleanupResult, argv-direct, WITHOUT --force (git itself refuses a locked or dirty worktree), surfacing git's message verbatim on a refusal. Two Tauri commands emit report-changed on a real run so the UI re-scans. - UI (WorktreesModal.svelte): a Clean/Prune button -> dry-run -> confirm -> run -> re-scan, offered ONLY on rows git would actually clean (proven merged + clean, or prunable), never the main/dirty/locked/active worktree. In the browser dev build it degrades to 'copy cmd' (not exposed over HTTP). - Transport (api.ts, types.ts): dual-mode, throws in the browser. - Docs: README/CLAUDE/ROADMAP no longer claim the inventory is purely read-only; the deferred-Clean backlog item is now done. - Test: remove_deletes_a_real_worktree_without_force (a real temp repo + worktree, removed without --force).
4758c00 to
615a91f
Compare
|
Thanks for this, Jorge — really solid and conservative work. I read through it and the safety model is exactly right: no One thing I'd like to fix before merging — not a data-loss issue, a robustness one: The mutating path drops the safeguards the read path has. Two optional follow-ups (fine to fold in or skip):
Everything else looks great — once the timeout/stdin fix is in, happy to merge. 🙌 |
|
Merged — thanks, Jorge! 🙌 Shipping in v0.1.9. Since this came from a fork I couldn't push to directly, I folded the two review points into a small hardening commit on top when merging, so they're in:
Everything else went in as-is — the no- (I left the per-row Prune wording as-is for now — harmless, and the |
The Worktrees inventory is read-only today: a row can only copy a
git worktree removecommand for you to run in a terminal. This adds the action that was deliberately deferred — aCleanbutton (Tauri-only) that runs it for you, so disk hygiene stays in the app.It is the only action in arrow that mutates disk, so it is built conservatively:
src-tauri/src/worktrees.rs):remove_worktree/prune_worktrees→CleanupResult, argv-direct (no shell), without--force— git itself refuses a locked or dirty/untracked worktree, and the refusal is surfaced verbatim. Two Tauri commands emitreport-changedon a real run so the UI re-scans. The parser lib (src/lib.rs) stays git-free.WorktreesModal.svelte):Clean/Prune→ dry-run → confirmation → run → re-scan, offered only on rows git would actually clean (proven merged + clean, or prunable) — never the main, dirty, locked, or active worktree. In the browser dev build it degrades tocopy cmd(the mutating commands are not exposed over HTTP).api.ts,types.ts): dual-mode; throws in the browser.Cleanbacklog item is marked done.Honesty
The button never promises a removal git would refuse: no
--force, nobranch -d/-D, neverrm -rf. A squash/rebase-merged branch (shown as "can't confirm") gets no Clean button.Testing
remove_deletes_a_real_worktree_without_force— a real temp git repo + linked worktree, dry-run leaves it, real remove deletes it.cargo testgreen (parser + backend),cargo clippyclean,cargo fmtapplied, frontend builds.Branches off the current
main, so it applies cleanly on top of the existing Worktrees inventory.