Skip to content

Instantly share code, notes, and snippets.

@GaurangTandon
Created November 16, 2025 13:51
Show Gist options
  • Select an option

  • Save GaurangTandon/379ae9bbe4226a10d3b5f31b7968a3b3 to your computer and use it in GitHub Desktop.

Select an option

Save GaurangTandon/379ae9bbe4226a10d3b5f31b7968a3b3 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import re
import subprocess
import sys
def run_command(command):
"""Execute a shell command and return the output."""
try:
result = subprocess.run(command, shell=True, check=True, text=True, capture_output=True)
return result.stdout.strip()
except subprocess.CalledProcessError as e:
print(f"Error executing command: {command}")
print(f"Error message: {e.stderr}")
return None
def prune_and_delete_gone_branches():
"""Fetch with prune and delete local branches that no longer exist on remote."""
print("Fetching from remote and pruning...")
if run_command("git fetch -p") is None:
return False
print("Finding branches that no longer exist on remote...")
# Get all branches and their tracking info
branch_output = run_command("git branch -vv")
if branch_output is None:
return False
with open('branch_output.txt', 'w') as f:
f.write(branch_output)
# Find branches marked as gone
gone_branches = []
for line in branch_output.split('\n'):
bracket_pattern = re.compile(r'\[[^\]]*?\]')
matching = re.search(bracket_pattern, line)
if matching and matching.group(0).endswith(': gone]'):
# Extract branch name (first word after possible * for current branch)
parts = line.strip().split(' ')
branch_name = parts[0] if parts[0] != '*' else parts[1]
gone_branches.append(branch_name)
if not gone_branches:
print("No branches to delete. All branches are tracking existing remotes.")
return True
# Delete the branches
print(f"Found {len(gone_branches)} branch(es) to delete:")
for branch in gone_branches:
print(f" - {branch}")
confirm = input("\nDo you want to delete these branches? (y/N): ").lower()
if confirm != 'y':
print("Operation cancelled.")
return False
success_count = 0
for branch in gone_branches:
print(f"Deleting branch '{branch}'...")
result = run_command(f"git branch -D {branch}")
if result is not None:
success_count += 1
print(f" ✓ {result}")
else:
print(f" ✗ Failed to delete branch '{branch}'")
print(f"\n{success_count} of {len(gone_branches)} branches successfully deleted.")
return True
if __name__ == "__main__":
print("Git Branch Cleanup Utility")
print("=========================")
success = prune_and_delete_gone_branches()
sys.exit(0 if success else 1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment