From 36f21e46e9f73eee4ecbaa2f8038493a7b512b6d Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Mar 20 2017 17:17:19 +0000 Subject: [PATCH 1/5] When diffing the branches, do not browse master all the time, once is enough We used to iterate through the branches, then browse master/HEAD then browse the branch to see if it has commits that aren't in master/HEAD. With this commit, we'll browse master/HEAD just once at the start, then iterate through the branches, skip the branch that is equivalent to master/HEAD and check the other to see if they have commits not present in master. --- diff --git a/pagure/internal/__init__.py b/pagure/internal/__init__.py index 134688b..be7bbfc 100644 --- a/pagure/internal/__init__.py +++ b/pagure/internal/__init__.py @@ -265,36 +265,32 @@ def get_pull_request_ready_branch(): reponame = pagure.get_repo_path(repo) repo_obj = pygit2.Repository(reponame) - branches = {} - - for branchname in repo_obj.listall_branches(): - branch = repo_obj.lookup_branch(branchname) - - diff_commits = [] - - parentpath = os.path.join( - pagure.APP.config['GIT_FOLDER'], repo.path) + if not repo_obj.is_empty and not repo_obj.head_is_unborn: + compare_branch = repo_obj.lookup_branch( + repo_obj.head.shorthand) + compare_commits = [ + commit.oid.hex + for commit in repo_obj.walk( + compare_branch.get_object().hex, + pygit2.GIT_SORT_TIME) + ] + else: + compare_branch = None - orig_repo = pygit2.Repository(parentpath) + compare_commits = [] - if not repo_obj.is_empty and not orig_repo.is_empty \ - and repo_obj.listall_branches() > 1: + branches = {} - if not orig_repo.head_is_unborn: - compare_branch = orig_repo.lookup_branch( - orig_repo.head.shorthand) - else: - compare_branch = None + if repo_obj.listall_branches() > 1: + for branchname in repo_obj.listall_branches(): + branch = repo_obj.lookup_branch(branchname) - compare_commits = [] + # Do not compare a branch to itself + if compare_branch \ + and compare_branch.branch_name == branch.branch_name: + continue - if compare_branch: - compare_commits = [ - commit.oid.hex - for commit in orig_repo.walk( - compare_branch.get_object().hex, - pygit2.GIT_SORT_TIME) - ] + diff_commits = [] repo_commit = repo_obj[branch.get_object().hex] @@ -304,8 +300,8 @@ def get_pull_request_ready_branch(): break diff_commits.append(commit.oid.hex) - if diff_commits: - branches[branchname] = diff_commits + if diff_commits: + branches[branchname] = diff_commits prs = pagure.lib.search_pull_requests( pagure.SESSION, From bc1b12b8c9dc5cdd41667674d1ba85130dbc1b37 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Mar 20 2017 17:17:19 +0000 Subject: [PATCH 2/5] Only iterate through master if there are more than one branch --- diff --git a/pagure/internal/__init__.py b/pagure/internal/__init__.py index be7bbfc..44ba017 100644 --- a/pagure/internal/__init__.py +++ b/pagure/internal/__init__.py @@ -265,23 +265,23 @@ def get_pull_request_ready_branch(): reponame = pagure.get_repo_path(repo) repo_obj = pygit2.Repository(reponame) - if not repo_obj.is_empty and not repo_obj.head_is_unborn: - compare_branch = repo_obj.lookup_branch( - repo_obj.head.shorthand) - compare_commits = [ - commit.oid.hex - for commit in repo_obj.walk( - compare_branch.get_object().hex, - pygit2.GIT_SORT_TIME) - ] - else: - compare_branch = None + branches = {} + if not repo_obj.is_empty and repo_obj.listall_branches() > 1: + if not repo_obj.head_is_unborn: + compare_branch = repo_obj.lookup_branch( + repo_obj.head.shorthand) + compare_commits = [ + commit.oid.hex + for commit in repo_obj.walk( + compare_branch.get_object().hex, + pygit2.GIT_SORT_TIME) + ] + else: + compare_branch = None - compare_commits = [] + compare_commits = [] - branches = {} - if repo_obj.listall_branches() > 1: for branchname in repo_obj.listall_branches(): branch = repo_obj.lookup_branch(branchname) From a370bb224595cac049fe3c04e53e516ee0994520 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Mar 20 2017 17:17:19 +0000 Subject: [PATCH 3/5] Optimize diffing two branches Instead of building the list of all the commits of one and then iterating through the other to see if it has commits shared with the first, we now go through the commits on both branches one step at a time and check if they have overlapping commits at each steps. --- diff --git a/pagure/internal/__init__.py b/pagure/internal/__init__.py index 44ba017..9e4733b 100644 --- a/pagure/internal/__init__.py +++ b/pagure/internal/__init__.py @@ -270,12 +270,6 @@ def get_pull_request_ready_branch(): if not repo_obj.head_is_unborn: compare_branch = repo_obj.lookup_branch( repo_obj.head.shorthand) - compare_commits = [ - commit.oid.hex - for commit in repo_obj.walk( - compare_branch.get_object().hex, - pygit2.GIT_SORT_TIME) - ] else: compare_branch = None @@ -290,18 +284,35 @@ def get_pull_request_ready_branch(): and compare_branch.branch_name == branch.branch_name: continue - diff_commits = [] - repo_commit = repo_obj[branch.get_object().hex] - for commit in repo_obj.walk( - repo_commit.oid.hex, pygit2.GIT_SORT_TIME): - if commit.oid.hex in compare_commits: + if compare_branch: + main_walker = repo_obj.walk( + compare_branch.get_object().hex, + pygit2.GIT_SORT_TIME) + branch_walker = repo_obj.walk( + repo_commit.oid.hex, + pygit2.GIT_SORT_TIME) + main_commits = set() + branch_commits = list() + while 1: + if compare_branch: + try: + com = main_walker.next() + main_commits.add(com.hex) + except StopIteration: + pass + try: + com = branch_walker.next() + branch_commits.append(com.hex) + except StopIteration: + break + + if main_commits.intersection(set(branch_commits)): break - diff_commits.append(commit.oid.hex) - if diff_commits: - branches[branchname] = diff_commits + if branch_commits: + branches[branchname] = branch_commits prs = pagure.lib.search_pull_requests( pagure.SESSION, From ad6a1b68133ec6acc427544e33993d46948b4371 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Mar 20 2017 17:17:19 +0000 Subject: [PATCH 4/5] Exclude the commit shared between the branches from the diff list --- diff --git a/pagure/internal/__init__.py b/pagure/internal/__init__.py index 9e4733b..19e89a1 100644 --- a/pagure/internal/__init__.py +++ b/pagure/internal/__init__.py @@ -303,13 +303,14 @@ def get_pull_request_ready_branch(): except StopIteration: pass try: - com = branch_walker.next() - branch_commits.append(com.hex) + branch_commit = branch_walker.next() except StopIteration: - break + branch_commit = None - if main_commits.intersection(set(branch_commits)): + if main_commits.intersection(set( + branch_commits + [branch_commit.hex])): break + branch_commits.append(branch_commit.hex) if branch_commits: branches[branchname] = branch_commits From 27110011d5531c40edae9d3500038e19a978cce9 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Mar 20 2017 17:17:19 +0000 Subject: [PATCH 5/5] Small clean up --- diff --git a/pagure/internal/__init__.py b/pagure/internal/__init__.py index 19e89a1..cc5e53e 100644 --- a/pagure/internal/__init__.py +++ b/pagure/internal/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ - (c) 2015-2016 - Copyright Red Hat Inc + (c) 2015-2017 - Copyright Red Hat Inc Authors: Pierre-Yves Chibon @@ -273,9 +273,6 @@ def get_pull_request_ready_branch(): else: compare_branch = None - compare_commits = [] - - for branchname in repo_obj.listall_branches(): branch = repo_obj.lookup_branch(branchname)