From d05f1d05ac7601d35705737cc4e858295b390f1a Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Jan 25 2020 15:39:49 +0000 Subject: Only consider the most recently active branches for new PR Instead of considering all the branches in the git repository when we are looking for the branches available to open new PRs from, we are now considering only the 8 latest active branches. This should optimize the "New PR" drop-down button in the UI quite significantly in large repositories. Fixes https://pagure.io/pagure/issue/4587 Signed-off-by: Pierre-Yves Chibon --- diff --git a/pagure/lib/repo.py b/pagure/lib/repo.py index 4592eb1..fb6774d 100644 --- a/pagure/lib/repo.py +++ b/pagure/lib/repo.py @@ -156,3 +156,39 @@ class PagureRepo(pygit2.Repository): cmd.extend(["--", target]) return run_command(cmd, cwd=path) + + @staticmethod + def get_active_branches(path, nbranch=8, catch_exception=False): + """ Returns the active branches in the git repo at the specified + location. + + :arg path: the location of the git repo + :type path: str + :kwarg nbranch: the number of active branches to consider, defaults to + 6 + :type nbranch: int + :kwarg catch_exception: Whether or not this method should silently + ignore all exception raised when running the git command and return + an empty list in those situations. Defaults to False. + :type catch_exception: boolean + """ + cmd = [ + "git", + "for-each-ref", + "--count=%s" % nbranch, + "--sort=-committerdate", + "refs/heads/", + ] + output = [] + try: + cmd_output = run_command(cmd, path) + for row in cmd_output.split("\n"): + output.append( + row.replace("\t", " ") + .rsplit(" ", 1)[-1] + .replace("refs/heads/", "") + ) + except Exception: + if not catch_exception: + raise + return output diff --git a/pagure/lib/tasks.py b/pagure/lib/tasks.py index 8b98f82..5817945 100644 --- a/pagure/lib/tasks.py +++ b/pagure/lib/tasks.py @@ -1117,7 +1117,8 @@ def pull_request_ready_branch(self, session, namespace, name, user): repo = pagure.lib.query._get_project( session, name, user=user, namespace=namespace ) - repo_obj = pygit2.Repository(pagure.utils.get_repo_path(repo)) + repo_path = pagure.utils.get_repo_path(repo) + repo_obj = pygit2.Repository(repo_path) if repo.is_fork and repo.parent: parentreponame = pagure.utils.get_repo_path(repo.parent) @@ -1127,7 +1128,13 @@ def pull_request_ready_branch(self, session, namespace, name, user): branches = {} if not repo_obj.is_empty and len(repo_obj.listall_branches()) > 0: - for branchname in repo_obj.listall_branches(): + branch_names = ( + pagure.lib.repo.PagureRepo.get_active_branches( + repo_path, catch_exception=True + ) + or repo_obj.listall_branches() + ) + for branchname in branch_names: compare_branch = None if ( not parent_repo_obj.is_empty