Skip to content

Instantly share code, notes, and snippets.

@robballou
Created January 14, 2013 18:06
Show Gist options
  • Save robballou/4531991 to your computer and use it in GitHub Desktop.
Save robballou/4531991 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
import argparse
import sh
import re
import os
def verbose(message, options={}):
"""Display a message if we are using verbose mode"""
if 'verbose' not in options or not options.verbose:
return
print message
def change_remotes(directory, options={}):
"""
Change the remote URL for a directory with repositories
Note that this is currently setup so that this is a parent folder
of git repositories.
"""
current_directory = os.path.curdir
items = os.listdir(directory)
for item in items:
# skip hidden items, items like "." and ".."
if item.startswith('.'):
continue
full_path = "%s/%s" % (directory, item)
# ignore items that are not directories
if not os.path.isdir(full_path):
continue
# ignore items that do not have a ".git" folder within them
if not os.path.isdir("%s/.git" % full_path):
continue
# get the origin url
os.chdir(full_path)
remotes = parse_remotes(sh.git("remote", "-v"))
# if this git repo doesn't have a remote with this name, skip it
if options.remote not in remotes:
continue
if options.match:
url = remotes[options.remote]
if not re.match(options.match, url):
continue
# make the replacements
new_url = re.sub(options.source, options.replace, remotes[options.remote])
verbose("%-40s%s" % (item, remotes[options.remote]), options)
verbose("%-40s%s" % ("", new_url), options)
verbose("", options)
if not options.test:
sh.git("remote", "set-url", options.remote, new_url)
os.chdir(current_directory)
def parse_remotes(output):
"""Parse the remote information from git"""
lines = output.splitlines()
remotes = {}
for line in lines:
matches = re.match(r'^(\S+)\s(\S+)', line)
if matches and matches.group(1) not in remotes:
remotes[matches.group(1)] = matches.group(2)
return remotes
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Set the remotes for all git directories')
parser.add_argument('directory', default="~/git")
parser.add_argument('source', help="Pattern for re.sub()")
parser.add_argument('replace', help="Replacement for re.sub()")
parser.add_argument('-m', '--match')
parser.add_argument('-r', '--remote', default='origin')
parser.add_argument('-v', '--verbose', default=False, action="store_true")
parser.add_argument('-t', '--test-only', dest="test", default=False, action="store_true")
args = parser.parse_args()
change_remotes(args.directory, args)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment