summaryrefslogtreecommitdiff
path: root/app/finders/merge_requests/oldest_per_commit_finder.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/finders/merge_requests/oldest_per_commit_finder.rb')
-rw-r--r--app/finders/merge_requests/oldest_per_commit_finder.rb32
1 files changed, 29 insertions, 3 deletions
diff --git a/app/finders/merge_requests/oldest_per_commit_finder.rb b/app/finders/merge_requests/oldest_per_commit_finder.rb
index f50db43d7d2..5360f301036 100644
--- a/app/finders/merge_requests/oldest_per_commit_finder.rb
+++ b/app/finders/merge_requests/oldest_per_commit_finder.rb
@@ -15,19 +15,45 @@ module MergeRequests
# Returns a Hash that maps a commit ID to the oldest merge request that
# introduced that commit.
def execute(commits)
+ mapping = {}
+ shas = commits.map(&:id)
+
+ # To include merge requests by the commit SHA, we don't need to go through
+ # any diff rows.
+ #
+ # We can't squeeze all this into a single query, as the diff based data
+ # relies on a GROUP BY. On the other hand, retrieving MRs by their merge
+ # SHAs separately is much easier, and plenty fast.
+ @project
+ .merge_requests
+ .preload_target_project
+ .by_merge_commit_sha(shas)
+ .each do |mr|
+ # Merge SHAs can't be in the merge request itself. It _is_ possible a
+ # newer merge request includes the merge commit, but in that case we
+ # still want the oldest merge request.
+ mapping[mr.merge_commit_sha] = mr
+ end
+
+ remaining = shas - mapping.keys
+
+ return mapping if remaining.empty?
+
id_rows = MergeRequestDiffCommit
- .oldest_merge_request_id_per_commit(@project.id, commits.map(&:id))
+ .oldest_merge_request_id_per_commit(@project.id, remaining)
mrs = MergeRequest
.preload_target_project
.id_in(id_rows.map { |r| r[:merge_request_id] })
.index_by(&:id)
- id_rows.each_with_object({}) do |row, hash|
+ id_rows.each do |row|
if (mr = mrs[row[:merge_request_id]])
- hash[row[:sha]] = mr
+ mapping[row[:sha]] = mr
end
end
+
+ mapping
end
end
end