feat(web): find and clean up unused worktrees from the branch menu - #172
Merged
Merged
Conversation
Nothing could ask the server which worktrees a repository has, so the UI had no way to show them or judge whether one was safe to delete. Adds a vcs.listWorktrees RPC that enumerates the checkouts and enriches each with the two facts a cleanup decision needs: uncommitted changes, and commits the default branch cannot reach. Wired through the git workflow service, the WebSocket handler table, and the web RPC client.
The client needs the same answer the server's removal guard computes -- which threads still use a worktree -- so the pure logic lived on the wrong side of the wire. Moves the classification (and the workspace path normalizer it depends on) to @threadlines/shared/worktreeUsage; the guard keeps its effectful wrapper and imports the policy. The pure tests move with it.
The composer's branch picker tagged a branch checked out in another worktree, but the source control panel's Switch to list did not, so the same branch read as plain in one place and tagged in the other. Both pickers now derive the tag from one helper, which compares the branch's checkout against the project's root rather than the checkout being viewed.
Deleting an archived thread dispatched the delete and returned, so the worktree it was the last thread linked to was never offered for cleanup and leaked. The archived path now resolves the thread and its project from the archived snapshot and runs the same offer as the live path. The "only thread linked" check weighs live and archived threads together in both directions, so neither path offers to remove a folder the other still points at.
Worktrees only ever got removed through the prompt on thread delete, and
several paths skipped it, so a project quietly accumulated checkouts with no
way to see or remove them.
The source control branch menu gains a "Clean up worktrees..." row with a count
of how many are going spare, and a spinner in that same slot while the list
loads. It opens a dialog listing every checkout nothing is running in, each
with its branch and a note when deleting it would lose something: uncommitted
changes, commits the default branch never saw, or an archived thread still
pointing there. Risk-free rows start ticked, risky ones do not, and checkouts
in use are listed greyed out so the picture is complete. Confirming deletes
them one at a time and reports the outcome on each row, so a failure stays on
screen instead of scrolling past in a toast. The server's removal guard still
has the final word.
Each row also offers to move the thread into that checkout, so its uncommitted
files and unshipped commits can be read in the panel before deciding. That runs
the same checkout switch the composer's branch picker performs.
Branches left over from before a history rewrite share no commit with the
default branch, and counting there reported their entire history as unshipped
work ("1731 commits not on main"). The listing now checks for a merge base
first and reports unrelated history instead of a number.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
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.
Worktrees pile up with no way to see or remove them: the only cleanup was the delete-thread prompt, and several paths skipped it (archived threads entirely).
The source control panel's branch menu gains a "Clean up worktrees..." entry showing a live count of unused checkouts. It opens a batch dialog: each secondary worktree is a checkbox row with its branch and what deleting it would cost (uncommitted changes, unmerged commits, an archived thread pointing at it, or no shared history with main for pre-rewrite checkouts). Risk-free rows start checked, Select all/none toggles the rest, in-use rows are shown but untouchable, and deletions run one at a time with per-row progress and inline failures. Each row also gets a switch-checkout button to inspect the worktree in the panel before deciding.
Supporting changes: a new vcs.listWorktrees RPC with dirty/unmerged/unrelated-history state per checkout, the worktree-usage classification moved to a shared module so client and server agree on "in use", deleting an archived thread now offers the same worktree cleanup as live threads (with the orphan check looking across both live and archived sets), and the panel's Switch-to list now shows the same worktree badge as the composer's branch picker.