Skip to content

Comments

Auto-cleanup orphaned worktrees on app startup#202

Draft
Copilot wants to merge 2 commits intomainfrom
copilot/auto-cleanup-orphaned-worktrees
Draft

Auto-cleanup orphaned worktrees on app startup#202
Copilot wants to merge 2 commits intomainfrom
copilot/auto-cleanup-orphaned-worktrees

Conversation

Copy link
Contributor

Copilot AI commented Feb 23, 2026

Worktrees accumulated silently over time with no automatic cleanup — each consuming up to 12 GB. Users had to manually cross-reference git worktree list against active sessions to clean up stale entries.

Changes

RepoManager

  • FindOrphanedWorktrees(worktrees, activeWorktreeIds) — pure static function; returns tracked worktrees whose IDs are absent from the active set. Used as the identification layer and independently testable.
  • IsSafeToRemoveAsync — classifies an orphan as safe to auto-remove when the directory is missing or the working tree is clean (git status --porcelain empty) and the remote tracking branch is gone (git branch -vv shows gone for the current branch).
  • PruneOrphanedWorktreesAsync(activeWorktreeIds, ct) — iterates orphans, removes safe ones via existing RemoveWorktreeAsync (which handles git worktree remove --force + fallback prune). Per-worktree errors are caught individually so one failure doesn't abort the rest.

CopilotService

  • PruneOrphanedWorktreesAsync(ct) (private) — collects active worktree IDs from Organization.Sessions and Organization.Groups, then delegates to _repoManager.PruneOrphanedWorktreesAsync.
  • Wired into InitializeAsync as fire-and-forget after ReconcileOrganization(), consistent with how FetchAvailableModelsAsync is launched — startup is not blocked.
// Worktrees with no session reference + clean state + [gone] upstream → removed automatically
var activeWorktreeIds = Organization.Sessions.Select(m => m.WorktreeId)
    .Concat(Organization.Groups.Select(g => g.WorktreeId));
await _repoManager.PruneOrphanedWorktreesAsync(activeWorktreeIds, ct);

Tests

Five new cases in RepoManagerTests cover FindOrphanedWorktrees: normal orphan detection, all-active (no orphans), null IDs treated as inactive, empty worktree list, and empty active set.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • l7avsblobprodcus319.vsblob.vsassets.io
    • Triggering command: /usr/bin/dotnet dotnet restore --no-dependencies /home/REDACTED/work/PolyPilot/.codeql-scratch/dbs/csharp/working/622A4908CDBE24FF535A100F8AC55E4F/missingpackages_workingdir --packages /home/REDACTED/work/PolyPilot/.codeql-scratch/dbs/csharp/working/missingpackages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal --configfile /home/REDACTED/work/PolyPilot/.codeql-scratch/dbs/csharp/working/nugetconfig/nuget.config --force (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Auto-cleanup orphaned worktrees on session creation or app startup</issue_title>
<issue_description>## Problem

Worktrees accumulate silently over time and are never automatically cleaned up. Each worktree can consume 1-12 GB of disk space. After several sessions, users can end up with many orphaned worktrees from completed/abandoned work (branches deleted from remote, sessions no longer active, etc.).

Today, cleanup requires the user to manually run git worktree list, cross-reference against active sessions, and git worktree remove each stale one.

Proposed Solution

Add automatic worktree cleanup logic, triggered on app startup or new session creation:

  1. List all worktrees on disk under ~/.polypilot/worktrees/
  2. Cross-reference against active sessions (check _sessions dictionary and Organization.Sessions)
  3. Identify orphaned worktrees — those with no active session pointing to them
  4. Classify orphans by risk level:
    • Safe to auto-remove: Clean (no dirty files) + remote branch gone ([gone] tracking status)
    • Prompt before removing: Has uncommitted changes or untracked files
    • Keep: Has active session or running processes
  5. Auto-remove safe orphans (or at minimum, surface them to the user with an option to clean up)
  6. Run git worktree prune after cleanup to remove stale git refs

Additional Context

RepoManager already has RemoveWorktreeAsync — this work is primarily about adding the discovery/reconciliation logic and hooking it into the session lifecycle.

Key files:

  • PolyPilot/Services/RepoManager.cs — worktree creation/removal
  • PolyPilot/Services/CopilotService.cs — session creation (CreateSessionAsync)
    </issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>
Copilot AI changed the title [WIP] Add auto-cleanup for orphaned worktrees on session creation Auto-cleanup orphaned worktrees on app startup Feb 23, 2026
Copilot AI requested a review from PureWeen February 23, 2026 19:15
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.

Auto-cleanup orphaned worktrees on session creation or app startup

2 participants