Skip to content

Instantly share code, notes, and snippets.

@jeetsukumaran
Last active June 14, 2020 22:03
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 jeetsukumaran/76f986f46d2ec12790b0cdbe81d4d56f to your computer and use it in GitHub Desktop.
Save jeetsukumaran/76f986f46d2ec12790b0cdbe81d4d56f to your computer and use it in GitHub Desktop.
#!/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