Created
December 26, 2014 03:42
-
-
Save houkanshan/9ca09ef52ef9db1fa08e 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 python | |
| # -*- coding: utf-8 -*- | |
| # This script helps removing Git branches. | |
| # Run it from a git repo dir. It will open the Git branches list | |
| # in your favorite editor. Delete some branches from the list. | |
| # Save and close the file. The script applies the changes to the repo. | |
| from subprocess import call, Popen, PIPE | |
| from os import getenv | |
| import re | |
| import sys | |
| args = sys.argv[1:] | |
| if not args: | |
| args = ['--merged', ' | sed \'/master/d\''] | |
| # configure commands used in this script | |
| editor_command = getenv('EDITOR') or 'vim' | |
| branch_command = 'git branch -a ' + ' '.join(args) | |
| mktemp_command = 'mktemp' | |
| own_remote = 'origin' | |
| # regex to check whether the branch is a remote branch | |
| remote_re = re.compile(r'remotes\/') | |
| def is_remote(branch): | |
| return bool(remote_re.findall(branch)) | |
| # takes 'git branch' output and returns a set of branches | |
| def branches_to_list(text): | |
| branches = set() | |
| for branch in re.split('\n', text): | |
| branch = re.sub(' .+', '', branch.lstrip()); | |
| #if is_remote(branch): | |
| #branch = branch.replace('remotes/', '') | |
| if branch: | |
| branches.add(branch) | |
| return branches | |
| # create a temp file | |
| tmp_file = Popen(mktemp_command, stdout=PIPE).communicate()[0].decode().rstrip() | |
| # write git branches to the temp file | |
| call('%s > %s' % (branch_command, tmp_file), shell=True) | |
| # get original branches | |
| original_branches = branches_to_list(open(tmp_file, 'r').read()) | |
| # edit the temp file with the editor command | |
| call('%s %s' % (editor_command, tmp_file), shell=True) | |
| # get new branches | |
| new_branches = branches_to_list(open(tmp_file, 'r').read()) | |
| # adding and renaming branches is not supported | |
| if(new_branches.difference(original_branches)): | |
| exit('Aborting! Do not add or rename branches, just remove them.') | |
| # remove branches with Git | |
| for branch in original_branches.difference(new_branches): | |
| if is_remote(branch): | |
| branch = branch.replace('remotes/', '') | |
| pushable = re.sub('/', ' :', branch, 1) | |
| print 'now delete remote: git push %s' % pushable | |
| if own_remote in branch: | |
| call('git push %s' % pushable, shell=True) | |
| else: | |
| call('git branch -r -d %s' % branch, shell=True) | |
| else: | |
| print 'now local: git push %s' % pushable | |
| call('git branch -D %s' % branch, shell=True) | |
| # just run `git remote prune origin` to remove local tracked branch | |
| # which is not exist on server | |
| call('git remote prune origin', shell=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment