diff options
author | Douwe Maan <douwe@selenight.nl> | 2018-12-28 12:18:50 +0100 |
---|---|---|
committer | Douwe Maan <douwe@selenight.nl> | 2019-01-02 15:31:34 +0100 |
commit | 7388a911aa61ad3a9fb061517e22e74427155b5e (patch) | |
tree | 55d9f68838962b99a970925bead07a612fc5a863 | |
parent | 8c2172f215f83893516c0f3cfad8a5daa7320a50 (diff) | |
download | gitlab-ce-7388a911aa61ad3a9fb061517e22e74427155b5e.tar.gz |
Consider all matching MRs to determine if user can push
-rw-r--r-- | app/models/project.rb | 26 | ||||
-rw-r--r-- | spec/models/project_spec.rb | 10 | ||||
-rw-r--r-- | spec/services/ci/retry_pipeline_service_spec.rb | 2 |
3 files changed, 24 insertions, 14 deletions
diff --git a/app/models/project.rb b/app/models/project.rb index 930f6c9911f..162222f2131 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1933,14 +1933,8 @@ class Project < ActiveRecord::Base def any_branch_allows_collaboration?(user) return false unless user - return false if empty_repo? - # Issue for N+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/49322 - Gitlab::GitalyClient.allow_n_plus_1_calls do - merge_requests_allowing_collaboration.any? do |merge_request| - merge_request.can_be_merged_by?(user) - end - end + fetch_branch_allows_collaboration(user) end def branch_allows_collaboration?(user, branch_name) @@ -1950,7 +1944,7 @@ class Project < ActiveRecord::Base memoized_results = strong_memoize(:branch_allows_collaboration) do Hash.new do |result, cache_key| - result[cache_key] = fetch_branch_allows_collaboration?(user, branch_name) + result[cache_key] = fetch_branch_allows_collaboration(user, branch_name) end end @@ -2028,8 +2022,10 @@ class Project < ActiveRecord::Base private - def merge_requests_allowing_collaboration - source_of_merge_requests.opened.where(allow_collaboration: true) + def merge_requests_allowing_collaboration(source_branch = nil) + relation = source_of_merge_requests.opened.where(allow_collaboration: true) + relation = relation.where(source_branch: source_branch) if source_branch + relation end def create_new_pool_repository @@ -2156,12 +2152,16 @@ class Project < ActiveRecord::Base raise ex end - def fetch_branch_allows_collaboration?(user, branch_name) + def fetch_branch_allows_collaboration(user, branch_name = nil) Gitlab::SafeRequestStore.fetch("project-#{id}:branch-#{branch_name}:user-#{user.id}:branch_allows_collaboration") do next false if empty_repo? - merge_request = merge_requests_allowing_collaboration.find_by(source_branch: branch_name) - merge_request&.can_be_merged_by?(user) + # Issue for N+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/49322 + Gitlab::GitalyClient.allow_n_plus_1_calls do + merge_requests_allowing_collaboration(branch_name).any? do |merge_request| + merge_request.can_be_merged_by?(user) + end + end end end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 131de62fe03..f195f7ce48e 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -3831,6 +3831,16 @@ describe Project do let(:user) { create(:user) } let(:target_project) { create(:project, :repository) } let(:project) { fork_project(target_project, nil, repository: true) } + let!(:local_merge_request) do + create( + :merge_request, + target_project: project, + target_branch: 'target-branch', + source_project: project, + source_branch: 'awesome-feature-1', + allow_collaboration: true + ) + end let!(:merge_request) do create( :merge_request, diff --git a/spec/services/ci/retry_pipeline_service_spec.rb b/spec/services/ci/retry_pipeline_service_spec.rb index 55445e71539..75042b29bea 100644 --- a/spec/services/ci/retry_pipeline_service_spec.rb +++ b/spec/services/ci/retry_pipeline_service_spec.rb @@ -285,7 +285,7 @@ describe Ci::RetryPipelineService, '#execute' do end it 'allows to retry failed pipeline' do - allow_any_instance_of(Project).to receive(:fetch_branch_allows_collaboration?).and_return(true) + allow_any_instance_of(Project).to receive(:branch_allows_collaboration?).and_return(true) allow_any_instance_of(Project).to receive(:empty_repo?).and_return(false) service.execute(pipeline) |