Commit e38fcc8c authored by Sean McGivern's avatar Sean McGivern

Handle error when fetching ref for MR with deleted source branch

If the ref doesn't exist, and the source branch is deleted, we can't get it back
easily. Previously, we ignored this error by shelling out, so replicate that
behaviour.
parent 3cf5eba3
......@@ -950,8 +950,6 @@ class MergeRequest < ActiveRecord::Base
source_project.repository, source_branch) do |commit|
if commit
target_project.repository.write_ref(ref_path, commit.sha)
else
raise Rugged::ReferenceError, 'source repository is empty'
end
end
end
......
......@@ -996,7 +996,11 @@ class Repository
if start_repository == self
yield commit(start_branch_name)
else
sha = start_repository.commit(start_branch_name).sha
start_commit = start_repository.commit(start_branch_name)
return yield nil unless start_commit
sha = start_commit.sha
if branch_commit = commit(sha)
yield branch_commit
......
---
title: Fix 500 error on merged merge requests when GitLab is restored from a backup
merge_request:
author:
type: fixed
......@@ -1660,12 +1660,40 @@ describe MergeRequest do
end
describe '#fetch_ref' do
it 'sets "ref_fetched" flag to true' do
before do
subject.update!(ref_fetched: nil)
end
subject.fetch_ref
context 'when the branch exists' do
it 'writes the ref' do
expect(subject.target_project.repository).to receive(:write_ref).with(subject.ref_path, /\h{40}/)
expect(subject.reload.ref_fetched).to be_truthy
subject.fetch_ref
end
it 'sets "ref_fetched" flag to true' do
subject.fetch_ref
expect(subject.reload.ref_fetched).to be_truthy
end
end
context 'when the branch does not exist' do
before do
subject.source_branch = 'definitely-not-master'
end
it 'does not write the ref' do
expect(subject.target_project.repository).not_to receive(:write_ref)
subject.fetch_ref
end
it 'sets "ref_fetched" flag to true' do
subject.fetch_ref
expect(subject.reload.ref_fetched).to be_truthy
end
end
end
......
......@@ -2110,4 +2110,51 @@ describe Repository, models: true do
end
end
end
describe '#with_repo_branch_commit' do
context 'when comparing with the same repository' do
let(:start_repository) { repository }
context 'when the branch exists' do
let(:start_branch_name) { 'master' }
it 'yields the commit' do
expect { |b| repository.with_repo_branch_commit(start_repository, start_branch_name, &b) }
.to yield_with_args(an_instance_of(::Commit))
end
end
context 'when the branch does not exist' do
let(:start_branch_name) { 'definitely-not-master' }
it 'yields nil' do
expect { |b| repository.with_repo_branch_commit(start_repository, start_branch_name, &b) }
.to yield_with_args(nil)
end
end
end
context 'when comparing with another repository' do
let(:forked_project) { create(:project, :repository) }
let(:start_repository) { forked_project.repository }
context 'when the branch exists' do
let(:start_branch_name) { 'master' }
it 'yields the commit' do
expect { |b| repository.with_repo_branch_commit(start_repository, start_branch_name, &b) }
.to yield_with_args(an_instance_of(::Commit))
end
end
context 'when the branch does not exist' do
let(:start_branch_name) { 'definitely-not-master' }
it 'yields nil' do
expect { |b| repository.with_repo_branch_commit(start_repository, start_branch_name, &b) }
.to yield_with_args(nil)
end
end
end
end
end
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