From 073550825cf56ddfb14fde962991a046a75b6878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dirk=20M=C3=BCller?= Date: Fri, 17 May 2024 14:41:42 +0200 Subject: [PATCH] Fixups to improve the conversion process --- lib/git.py | 216 +++++++++++++++++++++++++---------------------------- 1 file changed, 102 insertions(+), 114 deletions(-) diff --git a/lib/git.py b/lib/git.py index 411d734..15f802e 100644 --- a/lib/git.py +++ b/lib/git.py @@ -28,61 +28,68 @@ class Git: self.path.mkdir(parents=True, exist_ok=True) self.open() - def open(self): - subprocess.run( - ['git', 'init', '--object-format=sha256', '-b', 'factory'], + def git_run(self, args, **kwargs): + """Run a git command""" + if "env" in kwargs: + envs = kwargs["env"].copy() + del kwargs["env"] + else: + envs = os.environ.copy() + envs["GIT_LFS_SKIP_SMUDGE"] = "1" + envs["GIT_CONFIG_GLOBAL"] = "/dev/null" + return subprocess.run( + ["git"] + args, cwd=self.path, check=True, + env=envs, + **kwargs, ) + def open(self): + self.git_run(["init", "--object-format=sha256", "-b", "factory"]) + def is_dirty(self): """Check if there is something to commit""" - status_str = subprocess.run( - ['git', 'status', '--porcelain=2'], - cwd=self.path, + status_str = self.git_run( + ["status", "--porcelain=2"], stdout=subprocess.PIPE, - check=True - ).stdout.decode('utf-8') - return len(list(filter(None, status_str.split('\n')))) > 0 + ).stdout.decode("utf-8") + return len(list(filter(None, status_str.split("\n")))) > 0 def branches(self): - br=subprocess.run( - ['git', 'for-each-ref', '--format=%(refname:short)', 'refs/heads/'], - cwd=self.path, - check=True, - stdout=subprocess.PIPE - ).stdout.decode('utf-8').split() + br = ( + self.git_run( + ["for-each-ref", "--format=%(refname:short)", "refs/heads/"], + stdout=subprocess.PIPE, + ) + .stdout.decode("utf-8") + .split() + ) if len(br) == 0: - br.append('factory') # unborn branch? + br.append("factory") # unborn branch? return br - def branch(self, branch, commit='HEAD'): - commit = subprocess.run( - ['git', 'rev-parse', '--verify', '--end-of-options', commit + '^{commit}'], - cwd=self.path, - check=True, - stdout=subprocess.PIPE - ).stdout.decode('utf-8').strip() - return subprocess.run(['git', 'branch', branch, commit], check=True) + def branch(self, branch, commit="HEAD"): + commit = ( + self.git_run( + ["rev-parse", "--verify", "--end-of-options", commit + "^{commit}"], + stdout=subprocess.PIPE, + ) + .stdout.decode("utf-8") + .strip() + ) + return self.git_run(["branch", branch, commit]) def checkout(self, branch): """Checkout into the branch HEAD""" new_branch = False if branch not in self.branches(): - subprocess.run( - ['git', 'branch', '-q', branch, 'HEAD'], - cwd=self.path, - check=True - ) + self.git_run(["branch", "-q", branch, "HEAD"]) new_branch = True else: ref = f"refs/heads/{branch}" - if (self.path/'.git'/ref).exists(): - subprocess.run( - ['git', 'checkout', '-q', branch], - cwd=self.path, - check=True - ) + if (self.path / ".git" / ref).exists(): + self.git_run(["switch", "-q", branch]) return new_branch def commit( @@ -106,87 +113,73 @@ class Git: committer_time = committer_time if committer_time else user_time if self.is_dirty(): - subprocess.run( - ["git", "add", "--all", "."], - cwd=self.path, - check=True, - ) + self.git_run(["add", "--all", "."]) - tree_id = subprocess.run( - ['git', 'write-tree'], - cwd=self.path, - check=True, - stdout=subprocess.PIPE - ).stdout.decode('utf-8').strip() + tree_id = ( + self.git_run(["write-tree"], stdout=subprocess.PIPE) + .stdout.decode("utf-8") + .strip() + ) parent_array = [] if isinstance(parents, list): for parent in filter(None, parents): - parent_array = parent_array + ['-p', parent] + parent_array = parent_array + ["-p", parent] elif isinstance(parents, str): - parents_array = ['-p', parents] + parent_array = ["-p", parents] - commit_id = subprocess.run( - ['git', 'commit-tree'] + parent_array + [tree_id], - cwd=self.path, - env={ - "GIT_AUTHOR_NAME": user, - "GIT_AUTHOR_EMAIL": user_email, - "GIT_AUTHOR_DATE": f"{int(user_time.timestamp())} +0000", - "GIT_COMMITTER_NAME": committer, - "GIT_COMMITTER_EMAIL": committer_email, - "GIT_COMMITTER_DATE": f"{int(committer_time.timestamp())} +0000", - }, - input=message.encode('utf-8'), - check=True, - stdout=subprocess.PIPE - ).stdout.decode('utf-8').rstrip() - subprocess.run( - ['git', 'reset', '--soft', commit_id], - cwd=self.path, - check=True, + commit_id = ( + self.git_run( + ["commit-tree"] + parent_array + [tree_id], + env={ + "GIT_AUTHOR_NAME": user, + "GIT_AUTHOR_EMAIL": user_email, + "GIT_AUTHOR_DATE": f"{int(user_time.timestamp())} +0000", + "GIT_COMMITTER_NAME": committer, + "GIT_COMMITTER_EMAIL": committer_email, + "GIT_COMMITTER_DATE": f"{int(committer_time.timestamp())} +0000", + }, + input=message.encode("utf-8"), + stdout=subprocess.PIPE, + ) + .stdout.decode("utf-8") + .rstrip() ) + self.git_run(["reset", "--soft", commit_id]) return commit_id - def branch_head(self, branch='HEAD'): - return subprocess.run( - ['git', 'rev-parse', '--verify', '--end-of-options', branch], - cwd=self.path, - check=True, - stdout=subprocess.PIPE - ).stdout.decode('utf-8').strip() + def branch_head(self, branch="HEAD"): + return ( + self.git_run( + ["rev-parse", "--verify", "--end-of-options", branch], + stdout=subprocess.PIPE, + ) + .stdout.decode("utf-8") + .strip() + ) def set_branch_head(self, branch, commit): - return subprocess.run( - ['git', 'branch', '-f', branch, commit], - cwd=self.path, - check=True, - ) + return self.git_run(["update-ref", f"refs/heads/{branch}", commit]) def gc(self): logging.debug(f"Garbage recollect and repackage {self.path}") - subprocess.run( - ["git", "gc", "--auto"], - cwd=self.path, + self.git_run( + ["gc", "--auto"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, ) -# def clean(self): -# for path, _ in self.repo.status().items(): -# logging.debug(f"Cleaning {path}") -# try: -# (self.path / path).unlink() -# self.repo.index.remove(path) -# except Exception as e: -# logging.warning(f"Error removing file {path}: {e}") + # def clean(self): + # for path, _ in self.repo.status().items(): + # logging.debug(f"Cleaning {path}") + # try: + # (self.path / path).unlink() + # self.repo.index.remove(path) + # except Exception as e: + # logging.warning(f"Error removing file {path}: {e}") def add(self, filename): - subprocess.run( - ['git', 'add', filename], - cwd=self.path, - check=True, - ) + self.git_run(["add", filename]) def add_default_lfs_gitattributes(self, force=False): if not (self.path / ".gitattributes").exists() or force: @@ -240,10 +233,8 @@ class Git: return any(fnmatch.fnmatch(filename, line) for line in patterns) def remove(self, file: pathlib.Path): - subprocess.run( - ['git', 'rm', '-q', '--ignore-unmatch', file.name], - cwd=self.path, - check=True, + self.git_run( + ["rm", "-q", "-f", "--ignore-unmatch", file.name], ) patterns = self.get_specific_lfs_gitattributes() if file.name in patterns: @@ -270,22 +261,19 @@ class Git: if response.status_code not in (201, 409): print(response.data) url = f"gitea@src.opensuse.org:{org_name}/{repo_name}.git" - subprocess.run( - ['git', 'remote', 'add', 'origin', url], - cwd=self.path, - check=True, + self.git_run( + ["remote", "add", "origin", url], ) def push(self, force=False): - cmd = ['git', 'push']; - if force: - cmd.append('-f') - cmd.append('origin') - cmd.append('refs/heads/factory'); - cmd.append('refs/heads/devel'); - subprocess.run( - cmd, - cwd=self.path, - check=True, - ) + if "origin" not in self.git_run(["remote"]).stdout: + logger.warning("Not pushing to remote because no 'origin' configured") + return + cmd = ["push"] + if force: + cmd.append("-f") + cmd.append("origin") + cmd.append("refs/heads/factory") + cmd.append("refs/heads/devel") + self.git_run(cmd)