Commit b341e2dc authored by David Kim's avatar David Kim

Make merge_request_diff to return an empty MergeRequestDiff if nil

We currently have quite a few MergeRequests without any associated
MergeRequestDiffs which is not ideal, but there seems to be no simple
way to work around this other than falling back to returning an empty
MergeRequestDiff.
parent 5cd90761
...@@ -48,6 +48,7 @@ class MergeRequest < ApplicationRecord ...@@ -48,6 +48,7 @@ class MergeRequest < ApplicationRecord
# 1. There are arguments - in which case we might be trying to force-reload. # 1. There are arguments - in which case we might be trying to force-reload.
# 2. This association is already loaded. # 2. This association is already loaded.
# 3. The latest diff does not exist. # 3. The latest diff does not exist.
# 4. It doesn't have any merge_request_diffs - it returns an empty MergeRequestDiff
# #
# The second one in particular is important - MergeRequestDiff#merge_request # The second one in particular is important - MergeRequestDiff#merge_request
# is the inverse of MergeRequest#merge_request_diff, which means it may not be # is the inverse of MergeRequest#merge_request_diff, which means it may not be
...@@ -56,7 +57,7 @@ class MergeRequest < ApplicationRecord ...@@ -56,7 +57,7 @@ class MergeRequest < ApplicationRecord
def merge_request_diff def merge_request_diff
fallback = latest_merge_request_diff unless association(:merge_request_diff).loaded? fallback = latest_merge_request_diff unless association(:merge_request_diff).loaded?
fallback || super fallback || super || MergeRequestDiff.new(merge_request_id: id)
end end
belongs_to :head_pipeline, foreign_key: "head_pipeline_id", class_name: "Ci::Pipeline" belongs_to :head_pipeline, foreign_key: "head_pipeline_id", class_name: "Ci::Pipeline"
...@@ -404,7 +405,7 @@ class MergeRequest < ApplicationRecord ...@@ -404,7 +405,7 @@ class MergeRequest < ApplicationRecord
end end
def commits(limit: nil) def commits(limit: nil)
return merge_request_diff.commits(limit: limit) if persisted? return merge_request_diff.commits(limit: limit) if merge_request_diff.persisted?
commits_arr = if compare_commits commits_arr = if compare_commits
reversed_commits = compare_commits.reverse reversed_commits = compare_commits.reverse
...@@ -421,7 +422,7 @@ class MergeRequest < ApplicationRecord ...@@ -421,7 +422,7 @@ class MergeRequest < ApplicationRecord
end end
def commits_count def commits_count
if persisted? if merge_request_diff.persisted?
merge_request_diff.commits_count merge_request_diff.commits_count
elsif compare_commits elsif compare_commits
compare_commits.size compare_commits.size
...@@ -431,7 +432,7 @@ class MergeRequest < ApplicationRecord ...@@ -431,7 +432,7 @@ class MergeRequest < ApplicationRecord
end end
def commit_shas(limit: nil) def commit_shas(limit: nil)
return merge_request_diff.commit_shas(limit: limit) if persisted? return merge_request_diff.commit_shas(limit: limit) if merge_request_diff.persisted?
shas = shas =
if compare_commits if compare_commits
...@@ -492,11 +493,11 @@ class MergeRequest < ApplicationRecord ...@@ -492,11 +493,11 @@ class MergeRequest < ApplicationRecord
end end
def first_commit def first_commit
merge_request_diff ? merge_request_diff.first_commit : compare_commits.first compare_commits.present? ? compare_commits.first : merge_request_diff.first_commit
end end
def raw_diffs(*args) def raw_diffs(*args)
merge_request_diff ? merge_request_diff.raw_diffs(*args) : compare.raw_diffs(*args) compare.present? ? compare.raw_diffs(*args) : merge_request_diff.raw_diffs(*args)
end end
def diffs(diff_options = {}) def diffs(diff_options = {})
...@@ -557,7 +558,7 @@ class MergeRequest < ApplicationRecord ...@@ -557,7 +558,7 @@ class MergeRequest < ApplicationRecord
end end
def diff_base_commit def diff_base_commit
if persisted? if merge_request_diff.persisted?
merge_request_diff.base_commit merge_request_diff.base_commit
else else
branch_merge_base_commit branch_merge_base_commit
...@@ -565,7 +566,7 @@ class MergeRequest < ApplicationRecord ...@@ -565,7 +566,7 @@ class MergeRequest < ApplicationRecord
end end
def diff_start_commit def diff_start_commit
if persisted? if merge_request_diff.persisted?
merge_request_diff.start_commit merge_request_diff.start_commit
else else
target_branch_head target_branch_head
...@@ -573,7 +574,7 @@ class MergeRequest < ApplicationRecord ...@@ -573,7 +574,7 @@ class MergeRequest < ApplicationRecord
end end
def diff_head_commit def diff_head_commit
if persisted? if merge_request_diff.persisted?
merge_request_diff.head_commit merge_request_diff.head_commit
else else
source_branch_head source_branch_head
...@@ -581,7 +582,7 @@ class MergeRequest < ApplicationRecord ...@@ -581,7 +582,7 @@ class MergeRequest < ApplicationRecord
end end
def diff_start_sha def diff_start_sha
if persisted? if merge_request_diff.persisted?
merge_request_diff.start_commit_sha merge_request_diff.start_commit_sha
else else
target_branch_head.try(:sha) target_branch_head.try(:sha)
...@@ -589,7 +590,7 @@ class MergeRequest < ApplicationRecord ...@@ -589,7 +590,7 @@ class MergeRequest < ApplicationRecord
end end
def diff_base_sha def diff_base_sha
if persisted? if merge_request_diff.persisted?
merge_request_diff.base_commit_sha merge_request_diff.base_commit_sha
else else
branch_merge_base_commit.try(:sha) branch_merge_base_commit.try(:sha)
...@@ -597,7 +598,7 @@ class MergeRequest < ApplicationRecord ...@@ -597,7 +598,7 @@ class MergeRequest < ApplicationRecord
end end
def diff_head_sha def diff_head_sha
if persisted? if merge_request_diff.persisted?
merge_request_diff.head_commit_sha merge_request_diff.head_commit_sha
else else
source_branch_head.try(:sha) source_branch_head.try(:sha)
...@@ -758,7 +759,7 @@ class MergeRequest < ApplicationRecord ...@@ -758,7 +759,7 @@ class MergeRequest < ApplicationRecord
end end
def ensure_merge_request_diff def ensure_merge_request_diff
merge_request_diff || create_merge_request_diff merge_request_diff.persisted? || create_merge_request_diff
end end
def create_merge_request_diff def create_merge_request_diff
...@@ -1005,7 +1006,7 @@ class MergeRequest < ApplicationRecord ...@@ -1005,7 +1006,7 @@ class MergeRequest < ApplicationRecord
def closes_issues(current_user = self.author) def closes_issues(current_user = self.author)
if target_branch == project.default_branch if target_branch == project.default_branch
messages = [title, description] messages = [title, description]
messages.concat(commits.map(&:safe_message)) if merge_request_diff messages.concat(commits.map(&:safe_message)) if merge_request_diff.persisted?
Gitlab::ClosingIssueExtractor.new(project, current_user) Gitlab::ClosingIssueExtractor.new(project, current_user)
.closed_by_message(messages.join("\n")) .closed_by_message(messages.join("\n"))
...@@ -1421,7 +1422,7 @@ class MergeRequest < ApplicationRecord ...@@ -1421,7 +1422,7 @@ class MergeRequest < ApplicationRecord
end end
def has_commits? def has_commits?
merge_request_diff && commits_count.to_i > 0 merge_request_diff.persisted? && commits_count.to_i > 0
end end
def has_no_commits? def has_no_commits?
......
...@@ -77,6 +77,18 @@ describe Projects::MergeRequestsController do ...@@ -77,6 +77,18 @@ describe Projects::MergeRequestsController do
end end
end end
context 'when diff is missing' do
render_views
it 'renders merge request page' do
merge_request.merge_request_diff.destroy
go(format: :html)
expect(response).to be_successful
end
end
it "renders merge request page" do it "renders merge request page" do
expect(::Gitlab::GitalyClient).to receive(:allow_ref_name_caching).and_call_original expect(::Gitlab::GitalyClient).to receive(:allow_ref_name_caching).and_call_original
......
...@@ -52,10 +52,10 @@ describe Gitlab::ImportExport::MergeRequestParser do ...@@ -52,10 +52,10 @@ describe Gitlab::ImportExport::MergeRequestParser do
context 'when the diff is invalid' do context 'when the diff is invalid' do
let(:merge_request_diff) { build(:merge_request_diff, merge_request: merge_request, base_commit_sha: 'foobar') } let(:merge_request_diff) { build(:merge_request_diff, merge_request: merge_request, base_commit_sha: 'foobar') }
it 'sets the diff to nil' do it 'sets the diff to empty diff' do
expect(merge_request_diff).to be_invalid expect(merge_request_diff).to be_invalid
expect(merge_request_diff.merge_request).to eq merge_request expect(merge_request_diff.merge_request).to eq merge_request
expect(parsed_merge_request.merge_request_diff).to be_nil expect(parsed_merge_request.merge_request_diff).to be_empty
end end
end end
end end
......
...@@ -662,13 +662,12 @@ describe MergeRequest do ...@@ -662,13 +662,12 @@ describe MergeRequest do
end end
describe '#raw_diffs' do describe '#raw_diffs' do
let(:merge_request) { build(:merge_request) }
let(:options) { { paths: ['a/b', 'b/a', 'c/*'] } } let(:options) { { paths: ['a/b', 'b/a', 'c/*'] } }
context 'when there are MR diffs' do context 'when there are MR diffs' do
it 'delegates to the MR diffs' do let(:merge_request) { create(:merge_request, :with_diffs) }
merge_request.merge_request_diff = MergeRequestDiff.new
it 'delegates to the MR diffs' do
expect(merge_request.merge_request_diff).to receive(:raw_diffs).with(options) expect(merge_request.merge_request_diff).to receive(:raw_diffs).with(options)
merge_request.raw_diffs(options) merge_request.raw_diffs(options)
...@@ -676,6 +675,8 @@ describe MergeRequest do ...@@ -676,6 +675,8 @@ describe MergeRequest do
end end
context 'when there are no MR diffs' do context 'when there are no MR diffs' do
let(:merge_request) { build(:merge_request) }
it 'delegates to the compare object' do it 'delegates to the compare object' do
merge_request.compare = double(:compare) merge_request.compare = double(:compare)
......
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