Last active
June 14, 2020 22:03
-
-
Save jeetsukumaran/76f986f46d2ec12790b0cdbe81d4d56f 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 | |
# -*- coding: utf-8 -*- | |
import os | |
import pathlib | |
import sys | |
import argparse | |
import subprocess | |
""" | |
Finds all Git repositories under current directory and renames 'master' branch | |
to 'main', both remotely and locally. | |
Feel free to share/modify/whatever as long as you are not a racist. | |
Use at your own risk. | |
""" | |
def log_info(message): | |
sys.stderr.write("- {}\n".format(message)) | |
def execute(cmd, cwd, is_dry_run): | |
log_info("::: Executing: '{}'".format(" ".join(cmd))) | |
if not is_dry_run: | |
p = subprocess.Popen(cmd, cwd=cwd) | |
stdout, stderr = p.communicate() | |
return p.returncode | |
else: | |
return 0 | |
def fix_repo_branch_name(repo_dir, new_name, is_dry_run): | |
old_name = "master" | |
remote_name = "origin" | |
returncode = execute( | |
cmd=["git", "branch", "-m", old_name, new_name], | |
cwd=repo_dir, | |
is_dry_run=is_dry_run, | |
) | |
if returncode != 0: | |
return False | |
for cmd in ( | |
["git", "push"], | |
["git", "push", remote_name, ":{}".format(old_name)], | |
["git", "push", "--set-upstream", "origin", new_name], | |
["git", "fetch", remote_name], | |
["git", "remote", "prune", remote_name],): | |
returncode = execute(cmd=cmd, | |
cwd=repo_dir, | |
is_dry_run=is_dry_run) | |
if returncode != 0: | |
break | |
return True | |
def git_repo_dirs(root_dir=None): | |
if root_dir is None: | |
root_dir = os.path.curdir | |
root_dirpath = pathlib.Path(root_dir) | |
for path in root_dirpath.rglob("*"): | |
if path.is_dir() and path.stem == ".git": | |
yield path.parent | |
def main(): | |
parser = argparse.ArgumentParser(description=None) | |
parser.add_argument("--new-name", | |
default="main", | |
help="New name for branch [default='%(default)s'].") | |
parser.add_argument("--dry-run", | |
action="store_true", | |
default=False, | |
help="Do not execute changes -- just report procedures.") | |
parser.add_argument("--ignore-errors", | |
action="store_true", | |
default=False, | |
help="Do not stop on errors.") | |
args = parser.parse_args() | |
for git_repo_dir in git_repo_dirs(): | |
log_info("'{}'".format(os.path.abspath(git_repo_dir))) | |
success = fix_repo_branch_name(git_repo_dir, args.new_name, args.dry_run) | |
if not success and not args.ignore_errors: | |
sys.exit(1) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment