QuickTip: Clean Up Old Git Branches with PowerShell

Ever find yourself drowning in a sea of local Git branches that no longer exist remotely? I’ve been there, especially when hopping between features, hotfixes, and experiments. Manually cleaning them up is tedious. So, I wrote a PowerShell script to help automate that cleanup. And yes, it includes a safety check before deleting anything.

When working on multiple branches in a Git repository, it's easy to forget to clean up local branches after they've been merged and deleted on the remote. Over time, this clutters your workspace and can confuse you, especially if you switch between branches often.

What does the PowerShell script do:

  • Checks if a folder is a Git repository

  • Fetches the latest remote branch info

  • Lists all local branches

  • Compares them to remote branches

  • Identifies local branches that no longer exist remotely (excluding develop)

  • Ask for confirmation before deleting them

param (
    [string]$repoPath = (Get-Location)  # Default to the current location if no path is provided
)

# Check if the provided folder path is a Git repository
$gitFolder = Join-Path $repoPath ".git"
if (Test-Path $gitFolder) {
    Write-Host "Processing repository: $repoPath"

    # Navigate to the repository folder
    Set-Location $repoPath

    # Fetch the latest data from the remote
    git fetch --prune

    # Get all local branches (exclude remote branches)
    $localBranches = git branch --format '%(refname:short)'

    # Get all remote branches (exclude local branches)
    $remoteBranches = git branch -r --format '%(refname:short)' | ForEach-Object {
        if ($_ -like 'origin/*') {
            $_.Substring(7)  # Strip the 'origin/' prefix
        } else {
            $_
        }
    }

    # Find local branches that are not in the remote branches and exclude 'develop'
    $branchesToDelete = $localBranches | Where-Object { 
        $remoteBranches -notcontains $_ -and $_ -ne 'origin/HEAD' -and $_ -ne 'develop'
    }

    # Check if there are any branches to delete
    if ($branchesToDelete.Count -gt 0) {
        Write-Host "The following local branches are not available on the remote (excluding 'develop'):"
        $branchesToDelete | ForEach-Object { Write-Host $_ }

        # Ask for confirmation to delete all branches at once
        $confirmation = Read-Host "Do you want to delete these branches? (y/n)"
        if ($confirmation -eq 'y' -or $confirmation -eq 'Y') {
            foreach ($branch in $branchesToDelete) {
                Write-Host "Deleting local branch: $branch"
                git branch -D $branch
            }
        } else {
            Write-Host "Skipping branch deletion."
        }
    } else {
        Write-Host "No local branches need deletion."
    }

    Write-Host "Cleanup complete."
} else {
    Write-Host "The specified folder is not a Git repository: $repoPath"
}


How to Use It

Save this script as Cleanup-GitBranches.ps1, then run it from PowerShell:

.\Cleanup-GitBranches.ps1 -repoPath "C:\path\to\your\repo"

Or simply run it without a parameter if you're already in the repo folder:

.\Cleanup-GitBranches.ps1

Let me know if you’ve got suggestions to improve this or if you’ve built a similar tool! Always curious how others automate their dev workflows.