diff options
-rw-r--r-- | app/models/repository.rb | 6 | ||||
-rw-r--r-- | changelogs/unreleased/37442-api-branches-id-repository-branches-is-calling-gitaly-n-1-times-per-request.yml | 5 | ||||
-rw-r--r-- | lib/api/branches.rb | 9 | ||||
-rw-r--r-- | lib/api/entities.rb | 5 | ||||
-rw-r--r-- | lib/api/v3/branches.rb | 6 |
5 files changed, 17 insertions, 14 deletions
diff --git a/app/models/repository.rb b/app/models/repository.rb index ef715d982ae..eb7766d040c 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -906,13 +906,13 @@ class Repository branch = Gitlab::Git::Branch.find(self, branch_or_name) if branch - root_ref_sha = commit(root_ref).sha - same_head = branch.target == root_ref_sha + @root_ref_sha ||= commit(root_ref).sha + same_head = branch.target == @root_ref_sha merged = if pre_loaded_merged_branches pre_loaded_merged_branches.include?(branch.name) else - ancestor?(branch.target, root_ref_sha) + ancestor?(branch.target, @root_ref_sha) end !same_head && merged diff --git a/changelogs/unreleased/37442-api-branches-id-repository-branches-is-calling-gitaly-n-1-times-per-request.yml b/changelogs/unreleased/37442-api-branches-id-repository-branches-is-calling-gitaly-n-1-times-per-request.yml new file mode 100644 index 00000000000..11a11a289bf --- /dev/null +++ b/changelogs/unreleased/37442-api-branches-id-repository-branches-is-calling-gitaly-n-1-times-per-request.yml @@ -0,0 +1,5 @@ +--- +title: Improve performance of the /projects/:id/repository/branches API endpoint +merge_request: 15215 +author: +type: performance diff --git a/lib/api/branches.rb b/lib/api/branches.rb index 19152c9f395..cdef1b546a9 100644 --- a/lib/api/branches.rb +++ b/lib/api/branches.rb @@ -29,12 +29,11 @@ module API use :pagination end get ':id/repository/branches' do - branches = ::Kaminari.paginate_array(user_project.repository.branches.sort_by(&:name)) + repository = user_project.repository + branches = ::Kaminari.paginate_array(repository.branches.sort_by(&:name)) + merged_branch_names = repository.merged_branch_names(branches.map(&:name)) - # n+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/37442 - Gitlab::GitalyClient.allow_n_plus_1_calls do - present paginate(branches), with: Entities::Branch, project: user_project - end + present paginate(branches), with: Entities::Branch, project: user_project, merged_branch_names: merged_branch_names end resource ':id/repository/branches/:branch', requirements: BRANCH_ENDPOINT_REQUIREMENTS do diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 8f44a39238e..a382db92e8d 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -242,10 +242,7 @@ module API end expose :merged do |repo_branch, options| - # n+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/37442 - Gitlab::GitalyClient.allow_n_plus_1_calls do - options[:project].repository.merged_to_root_ref?(repo_branch.name) - end + options[:project].repository.merged_to_root_ref?(repo_branch, options[:merged_branch_names]) end expose :protected do |repo_branch, options| diff --git a/lib/api/v3/branches.rb b/lib/api/v3/branches.rb index 69cd12de72c..b201bf77667 100644 --- a/lib/api/v3/branches.rb +++ b/lib/api/v3/branches.rb @@ -14,9 +14,11 @@ module API success ::API::Entities::Branch end get ":id/repository/branches" do - branches = user_project.repository.branches.sort_by(&:name) + repository = user_project.repository + branches = repository.branches.sort_by(&:name) + merged_branch_names = repository.merged_branch_names(branches.map(&:name)) - present branches, with: ::API::Entities::Branch, project: user_project + present branches, with: ::API::Entities::Branch, project: user_project, merged_branch_names: merged_branch_names end desc 'Delete a branch' |