Skip to content

Instantly share code, notes, and snippets.

@ngoue
Created February 16, 2017 20:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ngoue/e1b318458c3a6149afbcc95ddb21e766 to your computer and use it in GitHub Desktop.
Save ngoue/e1b318458c3a6149afbcc95ddb21e766 to your computer and use it in GitHub Desktop.
Python script to change all the local remotes on my system to use my new GitHub username
#! /usr/bin/env python3
__doc__ = '''
Update all local repositories with new urls after
changing your GitHub username.
'''
import os, sys, subprocess, re
SEARCH_PATH = "/path/to/search"
OLD_GITHUB_USERNAME = "old-username"
NEW_GITHUB_USERNAME = "new-username"
GITHUB_URL_RE = re.compile(r'(.*?github\.com(?::|/))({})/(.*?\.git)'.format(OLD_GITHUB_USERNAME))
def main():
# Check Python version
try:
version_info = sys.version_info
if version_info.major < 3 | (version_info.major == 3 & version_info.minor < 5):
print("This script uses some features introduces in Python 3.5... Exiting...")
return
except AttributeError:
print("Good Ghandi, you're using an outdated version of Python... You'll need something newer to make this work...")
return
# Search for all .git repositories
args = [
"find",
SEARCH_PATH,
"-name",
".git",
"-type",
"d"
]
try:
repository_paths = run(args)
except subprocess.CalledProcessError as e:
print("Error finding repositories: {}".format(e))
return
# Handle each repository
for path in repository_paths:
# Navigate to the repository's parent directory
repo_parent = os.path.split(path)[0]
os.chdir(repo_parent)
# Get a list of remotes
args = [
"git",
"remote"
]
try:
remotes = run(args)
except subprocess.CalledProcessError as e:
print("Error finding remotes: {}".format(e))
continue
# Check each remote
for remote in remotes:
# Check the remote url
args = [
"git",
"remote",
"get-url",
remote
]
try:
remote_url = run(args)[0]
except subprocess.CalledProcessError as e:
print("Error getting remote url: {}".format(e))
continue
match = GITHUB_URL_RE.match(remote_url)
if match:
updated_remote_url = "{}{}/{}".format(match.group(1), NEW_GITHUB_USERNAME, match.group(3))
# Set the updated remote url
args = [
"git",
"remote",
"set-url",
remote,
updated_remote_url
]
try:
run(args)
except subprocess.CalledProcessError as e:
print("Error updating remote url: {}".format(e))
continue
print("Successfully updated remote url: {}".format(updated_remote_url))
def run(*args, **kwargs):
'''Shortcut to call `subprocess.run` and return the output of the command'''
# output to stdout unless overridden in kwargs
kwargs.setdefault('stdout', subprocess.PIPE)
# run the command
proc = subprocess.run(*args, **kwargs)
# check return code – raises `subprocess.CalledProcessError` if non-zero status
proc.check_returncode()
# parse the output
return proc.stdout.decode().strip().split('\n')
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment