Public/Remove-StaleGitBranches.ps1

<#
.SYNOPSIS
    Deletes local branches that have no associated worktree.
.DESCRIPTION
    Finds all local branches that are not checked out in any worktree and
    deletes them. Protected branches (main, master, develop) are never deleted.
    Use -DryRun to preview what would be deleted without making changes.
.EXAMPLE
    Remove-StaleGitBranches -DryRun
.EXAMPLE
    Remove-StaleGitBranches -RepoPath C:\repos\myrepo.git -ProtectedBranches main,master,develop,staging
#>

function Remove-StaleGitBranches {
    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
    param(
        [Parameter()]
        [switch] $DryRun,

        [Parameter()]
        [string[]] $ProtectedBranches = @('main', 'master', 'develop'),

        [Parameter()]
        [string] $RepoPath = (Get-Location).Path
    )

    $root = Get-GitRoot -Path $RepoPath

    $worktrees      = Get-WorktreeList -RepoPath $root
    $checkedOutBranches = ($worktrees | Where-Object { $_.Branch } | Select-Object -ExpandProperty Branch)

    $allBranches = git -C $root branch --format '%(refname:short)' 2>$null
    if ($LASTEXITCODE -ne 0) { throw "Failed to list branches in '$root'" }

    $staleBranches = $allBranches | Where-Object {
        $_ -notin $checkedOutBranches -and $_ -notin $ProtectedBranches
    }

    if (-not $staleBranches) {
        Write-Host "No stale branches found." -ForegroundColor Cyan
        return
    }

    if ($DryRun) {
        Write-Host "Stale branches that would be deleted (DryRun):" -ForegroundColor Yellow
        $staleBranches | ForEach-Object { Write-Host " $_" -ForegroundColor Yellow }
        return
    }

    foreach ($branch in $staleBranches) {
        if ($PSCmdlet.ShouldProcess($branch, "Delete stale branch")) {
            git -C $root branch -D $branch
            if ($LASTEXITCODE -ne 0) {
                Write-Warning "Failed to delete branch '$branch'"
            }
            else {
                Write-Host "Deleted stale branch: $branch" -ForegroundColor Yellow
            }
        }
    }
}