Commit a9f4517a authored by Igor Drozdov's avatar Igor Drozdov

Merge branch 'include-squash-commits-in-changelogs' into 'master'

Link squashed commits using the changelog API

See merge request gitlab-org/gitlab!56985
parents e5b99b51 baf6fa74
......@@ -18,8 +18,8 @@ module MergeRequests
mapping = {}
shas = commits.map(&:id)
# To include merge requests by the commit SHA, we don't need to go through
# any diff rows.
# To include merge requests by the merge/squash 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
......@@ -27,12 +27,17 @@ module MergeRequests
@project
.merge_requests
.preload_target_project
.by_merge_commit_sha(shas)
.by_merge_or_squash_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
# Merge/squash SHAs can't be in the merge request itself. It _is_
# possible a newer merge request includes the commit, but in that case
# we still want the oldest merge request.
#
# It's also possible that a merge request produces both a squashed
# commit and a merge commit. In that case we want to store the mapping
# for both the SHAs.
mapping[mr.squash_commit_sha] = mr if mr.squash_commit_sha
mapping[mr.merge_commit_sha] = mr if mr.merge_commit_sha
end
remaining = shas - mapping.keys
......
......@@ -276,6 +276,9 @@ class MergeRequest < ApplicationRecord
scope :by_squash_commit_sha, -> (sha) do
where(squash_commit_sha: sha)
end
scope :by_merge_or_squash_commit_sha, -> (sha) do
from_union([by_squash_commit_sha(sha), by_merge_commit_sha(sha)])
end
scope :by_related_commit_sha, -> (sha) do
from_union(
[
......
---
title: Link squashed commits using the changelog API
merge_request: 56985
author:
type: added
......@@ -77,6 +77,45 @@ RSpec.describe MergeRequests::OldestPerCommitFinder do
expect(described_class.new(project).execute(commits)).to eq(sha => mr)
end
it 'includes a merge request that was squashed into the target branch' do
project = create(:project)
sha = Digest::SHA1.hexdigest('foo')
mr = create(
:merge_request,
:merged,
target_project: project,
squash_commit_sha: sha
)
commits = [double(:commit, id: sha)]
expect(MergeRequestDiffCommit)
.not_to receive(:oldest_merge_request_id_per_commit)
expect(described_class.new(project).execute(commits)).to eq(sha => mr)
end
it 'includes a merge request for both a squash and merge commit' do
project = create(:project)
sha1 = Digest::SHA1.hexdigest('foo')
sha2 = Digest::SHA1.hexdigest('bar')
mr = create(
:merge_request,
:merged,
target_project: project,
squash_commit_sha: sha1,
merge_commit_sha: sha2
)
commits = [double(:commit1, id: sha1), double(:commit2, id: sha2)]
expect(MergeRequestDiffCommit)
.not_to receive(:oldest_merge_request_id_per_commit)
expect(described_class.new(project).execute(commits))
.to eq(sha1 => mr, sha2 => mr)
end
it 'includes the oldest merge request when a merge commit is present in a newer merge request' do
project = create(:project)
sha = Digest::SHA1.hexdigest('foo')
......
......@@ -420,6 +420,19 @@ RSpec.describe MergeRequest, factory_default: :keep do
end
end
describe '.by_merge_or_squash_commit_sha' do
subject { described_class.by_merge_or_squash_commit_sha([sha1, sha2]) }
let(:sha1) { '123abc' }
let(:sha2) { '456abc' }
let(:mr1) { create(:merge_request, :merged, squash_commit_sha: sha1) }
let(:mr2) { create(:merge_request, :merged, merge_commit_sha: sha2) }
it 'returns merge requests that match the given squash and merge commits' do
is_expected.to include(mr1, mr2)
end
end
describe '.by_related_commit_sha' do
subject { described_class.by_related_commit_sha(sha) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment