Streamline Your Git Workflow: (semi)-automated Branch Cleanup with PowerShell

As developers and scripters, our local Git repositories can quickly become cluttered with old, merged, or orphaned branches. This accumulation not only makes it harder to navigate your local branches but can also lead to confusion about what’s active and what’s not. Constantly running git branch -d or git fetch --prune manually across multiple repositories is tedious and easy to forget.

These PowerShell functions eliminates that headache by automating the identification and removal of these stale branches. Whether you’re working in a single repository or managing a directory full of them, this script helps maintain a clean and organized local Git environment, allowing you to focus on your active development and scripting tasks.

Requirements

To use this script effectively, you’ll need:

  • PowerShell 5.1 or later: The script is written in PowerShell.
  • Git installed and in your PATH: The script relies on standard Git commands.
  • Permissions: The script needs permission to navigate directories and execute Git commands.

Benefits

This script offers distinct advantages for maintaining a clean Git workspace:

  • Automated Cleanup: Automatically identifies and removes local branches that track deleted remote branches (“orphaned branches”) and branches that have already been merged into your main development line.
  • Supports Single or Multiple Repositories (-Recurse): Can be run in a single Git repository or recursively search through subdirectories to find and clean multiple repositories.
  • Clear Preview Mode (Show-OrphanedBranches): This function always shows you which branches would be deleted without making any changes. Using the -WhatIf parameter with Show-OrphanedBranches explicitly highlights that you are in a preview mode, giving you extra confidence.
  • Safe Deletion (Remove-DeletedRemoteBranches with -WhatIf): The cleanup function (Remove-DeletedRemoteBranches) supports a -WhatIf parameter, providing a crucial layer of safety to preview actual deletions before they occur.
  • Improved Workflow: Reduces manual effort and helps keep your local Git environment tidy, leading to a more efficient and less confusing development and scripting workflow.

Step-by-Step Guide

To make the Show-OrphanedBranches and Remove-DeletedRemoteBranches functions available every time you open PowerShell or the PowerShell Integrated Terminal in VS Code, you can add the script’s content to your PowerShell profile.

A PowerShell profile is simply a script that runs automatically when PowerShell starts. It’s an excellent way to customize your environment with functions, aliases, and variables you use frequently.

1. Check if you have a PowerShell profile:
In your PowerShell console, type:

Test-Path $Profile

2. Open or Create Your PowerShell Profile: This command will open your PowerShell profile file in your preferred editor (Notepad is the default, but if you have VS Code installed and in your PATH, code $profile is often more convenient).

  • To open with Notepad:
notepad $profile
  • To open with VS code
code $profile

Important:

  • If the file does not exist (i.e., Test-Path $profile returned False), your chosen editor (Notepad or VS Code) will prompt you to create a new file. Confirm that you want to create it.
  • If the file already exists, it will simply open for editing.

3. Paste the Script Content: Once the $profile file is open in your editor, copy the entire content of these functions and paste it into the $profile file.

If you have existing content in your profile, paste this content at the end of the file on a new line.

4. Save and Close: Save the $profile file (e.g., Ctrl+S in Notepad or VS Code) and close the editor.

Now, the next time you open a new PowerShell session (or a new integrated terminal in VS Code), the Show-OrphanedBranches and Remove-DeletedRemoteBranches functions will be automatically loaded and ready for use without needing to run a separate script first! This makes cleanup even more seamless.

Examples

Check Current Repository for Orphaned Branches

# Analyze branches in your current git repository
Show-OrphanedBranches

# Output
๐Ÿ” Analyzing branches in: C:\dev\my-project

๐Ÿ“‹ Branch Analysis Results for: C:\dev\my-project
================================================================================

๐Ÿ—‘๏ธ  Orphaned Branches (tracking deleted remotes):

Name            Status
----            ------
feature/login   Remote deleted
bugfix/typo     Remote deleted

โœ… Merged Branches:

Name              Status
----              ------
hotfix/readme     Merged into main
feature/cleanup   Merged into main

๐Ÿ“Š Summary: 4 branch(es) could be cleaned up in this repository

Use 'Remove-DeletedRemoteBranches' to clean them up.

Search all subdirectories for Git repositories

# Recursively find and analyze all git repos in subdirectories
Show-OrphanedBranches -Recurse

# Output
๐Ÿ” Found 3 git repository/repositories:
  โ€ข C:\dev\project-a
  โ€ข C:\dev\project-b
  โ€ข C:\dev\tools\helper-scripts

๐Ÿ“‹ All Branches That Can Be Cleaned Up:
================================================================================

๐Ÿ—‘๏ธ  Orphaned Branches (tracking deleted remotes):

Name              Status          Repository
----              ------          ----------
feature/auth      Remote deleted  C:\dev\project-a
old-feature       Remote deleted  C:\dev\project-b

โœ… Merged Branches:

Name                Status              Repository
----                ------              ----------
hotfix/bug-123      Merged into main    C:\dev\project-a
feature/refactor    Merged into main    C:\dev\project-b
update/docs         Merged into main    C:\dev\tools\helper-scripts

๐Ÿ“Š Summary: 5 branch(es) total across 3 repository/repositories

Use 'Remove-DeletedRemoteBranches -Recurse' to clean up all repositories.

Preview what would be deleted (dry run)

# See what would be deleted without actually deleting
Remove-DeletedRemoteBranches -WhatIf

# Output
๐Ÿงน Cleaning branches in: C:\dev\my-project
Would delete orphaned branch: feature/login
Would delete orphaned branch: bugfix/typo
Would delete merged branch: hotfix/readme
Would delete merged branch: feature/cleanup

Actual Clean Up Branches

# Clean up branches in current repository
Remove-DeletedRemoteBranches

# Output
๐Ÿงน Cleaning branches in: C:\dev\my-project
Deleted orphaned branch: feature/login
Deleted orphaned branch: bugfix/typo
Deleted merged branch: hotfix/readme
Deleted merged branch: feature/cleanup

Clean Up All Repositories (with preview first)

# First, see what would be cleaned up across all repos
Remove-DeletedRemoteBranches -Recurse -WhatIf

# Then actually clean them up
Remove-DeletedRemoteBranches -Recurse

# Output
๐Ÿงน Cleaning branches in: C:\dev\project-a
Deleted orphaned branch: feature/auth
Deleted merged branch: hotfix/bug-123

๐Ÿงน Cleaning branches in: C:\dev\project-b  
Deleted orphaned branch: old-feature
Deleted merged branch: feature/refactor

๐Ÿงน Cleaning branches in: C:\dev\tools\helper-scripts
Deleted merged branch: update/docs

Common Scenarios

When no cleanup is needed

โœ… No branches to cleanup in: C:\dev\clean-project

When not in Git Repository

Not in a git repository. Use -Recurse to search subdirectories.

Error handling example

โŒ Error analyzing repository C:\dev\broken-repo: fatal: not a git repository

Conclusion

This PowerShell script provides a simple yet powerful solution for managing and cleaning up your local Git branches. By automating the identification and removal of stale branches, it helps reduce clutter and cognitive load, allowing you to maintain a more organized and efficient development and scripting environment. Integrating this script into your routine and even your PowerShell profile can save you time and prevent the frustrations of a messy local Git setup. Sometimes, the best tools are the ones that quietly work in the background, keeping your workspace tidy so you can focus on what matters most