From 716540a4ec652b70a6e82abf3e250825ddc3b2ec Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jan 11 2021 11:51:48 +0000 Subject: Add the find_and_pack_branches script This script can be used if one wants to mass-rename branches in a pagure instance. The script will find all the branches that currently conflict with the new name and move their references to a packed-refs file. That is if the current branches are in fact part of a branch. If the target branch already exist with the exact same name, then the renaming will fail as we can't have two branches with the same name and two different reference, one in refs/heads and the other in packed-refs. Signed-off-by: Pierre-Yves Chibon --- diff --git a/find_and_pack_branches.py b/find_and_pack_branches.py new file mode 100644 index 0000000..18773f3 --- /dev/null +++ b/find_and_pack_branches.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 + +""" +Find all the branches named after a given name in "refs/heads" and move their +references to a "packed-refs" file so the files can be removed in "refs/heads". + +""" + +import argparse +import logging +import os +import sys + +_log = logging.getLogger(__name__) + + +RENAME_TO = "rawhide" + + +def _find_branch(folder): + heads_path = os.path.join(folder, "refs/heads") + target = os.path.join(heads_path, RENAME_TO) + + if not os.path.exists(target): + return + + _log.info(f"{target} found") + + if not os.path.isdir(target): + _log.info(f"{target} is not a directory, can't move it to packed-refs") + return + + packed_refs = "" + packed_refs_filename = os.path.join(folder, "packed-refs") + if os.path.exists(packed_refs_filename): + with open(packed_refs_filename) as stream: + packed_refs = stream.read().strip() + + for root, dirs, files in os.walk(target): + for filename in files: + refname = root.replace(heads_path, "") + if refname.startswith("/"): + refname = refname[1:] + with open(os.path.join(root, filename)) as stream: + ref = stream.read().strip() + refname_line = f"refs/heads/{refname}/{filename}" + if refname_line in packed_refs: + print(f"Ref {refname_line} already packed") + continue + print(ref, refname_line) + with open(packed_refs_filename, "a") as stream: + stream.write(f"{ref} {refname_line}") + + +def main(folder, namespace): + for root, dirs, files in os.walk(os.path.join(folder, namespace)): + for name in dirs: + if name.endswith(".git"): + _find_branch(os.path.join(root, name)) + + return 0 + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description=f"Find all the branches (or branch namespace) named {RENAME_TO}" + " and move them to packed-refs" + ) + parser.add_argument("folder", help="Folder where to look for git repos") + parser.add_argument("namespace", help="Namespace to work on") + parser.add_argument( + "--debug", + dest="debug", + action="store_true", + default=False, + help="Print the debugging output", + ) + args = parser.parse_args() + _log.setLevel(logging.INFO) + if args.debug: + _log.setLevel(logging.DEBUG) + + formatter = logging.Formatter("%(asctime)s - %(message)s") + ch = logging.StreamHandler() + ch.setFormatter(formatter) + _log.addHandler(ch) + + sys.exit(main(args.folder, args.namespace))