Created
December 12, 2014 02:32
-
-
Save ShawnMilo/62770d9762ed51690e7a to your computer and use it in GitHub Desktop.
This file contains 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 python | |
""" | |
Identify (and potentially delete) remote branches which have already | |
been merged into the current branch. | |
It works by using the "git merge-base" command to see if the other branch's | |
newest commit is already contained in the current branch. | |
Run normally it does nothing destructive. It will just list branches that | |
could be deleted. This information can be used selectively, or reviewed | |
and this script can be run with the word DELETE passed as its sole argument | |
to actually perform the git commands to delete these branches from the | |
'origin' repository. | |
""" | |
import sys | |
from subprocess import check_output, CalledProcessError | |
from collections import Counter | |
DO_DELETE = sys.argv[-1] == 'DELETE' | |
# Branches that should be ignored, and a blank space to clean | |
# up the output of 'git branch' above. | |
EXEMPT = set(('master',)) | |
def get_current_branch(): | |
""" | |
Get current branch using subprocess call to git. | |
""" | |
return check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip() | |
def main(): | |
""" | |
Check for (and optionally delete) the branches. | |
""" | |
current_branch = get_current_branch() | |
# Get remote branches. | |
branches = [ | |
x.strip() for x in check_output(['git', 'branch', '-r']).split('\n') | |
] | |
EXEMPT.add(current_branch) | |
counter = Counter() | |
for branch in branches: | |
if branch.split('/')[-1] in EXEMPT: | |
counter['skipped exempt branches'] += 1 | |
continue | |
try: | |
merge_base = check_output([ | |
'git', 'merge-base', current_branch, branch | |
]).strip() | |
except CalledProcessError: | |
sys.stderr.write("Unable to check branch {0}\n".format(branch)) | |
continue | |
branch_head = check_output([ | |
'git', 'log', '-n', '1', '--oneline', branch | |
]).split()[0] | |
assert len(branch_head.strip()) >= 7 | |
if merge_base.startswith(branch_head): | |
if DO_DELETE: | |
print "Removing old branch from server: '{0}'".format(branch) | |
remote, branch_name = branch.split('/')[-2:] | |
print check_output(['git', 'push', remote, ':' + branch_name]) | |
else: | |
info = check_output([ | |
'git', 'log', '-n 1', '--format="%an %ar"', branch | |
]) | |
info = info.replace('"', '').strip() | |
print "Would be deleted: '{0}', last updated by {1}".format( | |
branch, info | |
) | |
counter['to remove'] += 1 | |
else: | |
counter['leave alone'] += 1 | |
for key in counter: | |
print unicode(key).rjust(20, ' '), unicode(counter[key]).rjust(10, ' ') | |
if counter['to remove'] == 0: | |
print "\nCongratulations! Nothing to do." | |
elif not DO_DELETE: | |
print ( | |
"\nNothing done. Pass 'DELETE' as the " | |
"first argument to actually clear out the branches." | |
) | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment