diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-19 12:08:42 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-19 12:08:42 +0300 |
commit | b76ae638462ab0f673e5915986070518dd3f9ad3 (patch) | |
tree | bdab0533383b52873be0ec0eb4d3c66598ff8b91 /lib/gitlab/checks/changes_access.rb | |
parent | 434373eabe7b4be9593d18a585fb763f1e5f1a6f (diff) |
Add latest changes from gitlab-org/gitlab@14-2-stable-eev14.2.0-rc42
Diffstat (limited to 'lib/gitlab/checks/changes_access.rb')
-rw-r--r-- | lib/gitlab/checks/changes_access.rb | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/lib/gitlab/checks/changes_access.rb b/lib/gitlab/checks/changes_access.rb index 4e8b293a3e6..9ecc93f871b 100644 --- a/lib/gitlab/checks/changes_access.rb +++ b/lib/gitlab/checks/changes_access.rb @@ -29,11 +29,60 @@ module Gitlab true end + # All commits which have been newly introduced via any of the given + # changes. This set may also contain commits which are not referenced by + # any of the new revisions. + def commits + newrevs = @changes.map do |change| + newrev = change[:newrev] + newrev unless newrev.blank? || Gitlab::Git.blank_ref?(newrev) + end.compact + + return [] if newrevs.empty? + + @commits ||= project.repository.new_commits(newrevs, allow_quarantine: true) + end + + # All commits which have been newly introduced via the given revision. + def commits_for(newrev) + commits_by_id = commits.index_by(&:id) + + result = [] + pending = Set[newrev] + + # We go up the parent chain of our newrev and collect all commits which + # are new. In case a commit's ID cannot be found in the set of new + # commits, then it must already be a preexisting commit. + while pending.any? + rev = pending.first + pending.delete(rev) + + # Remove the revision from commit candidates such that we don't walk + # it multiple times. If the hash doesn't contain the revision, then + # we have either already walked the commit or it's not new. + commit = commits_by_id.delete(rev) + next if commit.nil? + + # Only add the parent ID to the pending set if we actually know its + # commit to guards us against readding an ID which we have already + # queued up before. + commit.parent_ids.each do |parent_id| + pending.add(parent_id) if commits_by_id.has_key?(parent_id) + end + + result << commit + end + + result + end + protected def single_access_checks! # Iterate over all changes to find if user allowed all of them to be applied changes.each do |change| + commits = Gitlab::Lazy.new { commits_for(change[:newrev]) } if Feature.enabled?(:changes_batch_commits) + # If user does not have access to make at least one change, cancel all # push by allowing the exception to bubble up Checks::SingleChangeAccess.new( @@ -41,7 +90,8 @@ module Gitlab user_access: user_access, project: project, protocol: protocol, - logger: logger + logger: logger, + commits: commits ).validate! end end |