Created
November 16, 2025 13:51
-
-
Save GaurangTandon/379ae9bbe4226a10d3b5f31b7968a3b3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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