summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLin Jen-Shin <godfat@godfat.org>2017-08-29 22:42:34 +0800
committerLin Jen-Shin <godfat@godfat.org>2017-08-29 22:42:34 +0800
commit9d3ee1ff139650e064a41fd90d34cd3f558c1099 (patch)
treeb77eb6c616567023a40b128c90cdd0c7f4a34467
parente6630d7f7276dc5cec2a02e32dc74a0a060886ab (diff)
downloadgitlab-ce-perf.slow-issuable.tar.gz
Further break with_repo_branch_commit into partsperf.slow-issuable
So it's more clear what could happen. Also add more tests about the behaviour.
-rw-r--r--app/models/repository.rb43
-rw-r--r--spec/models/repository_spec.rb36
2 files changed, 59 insertions, 20 deletions
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 04a76c365be..93017dfedf9 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -1000,29 +1000,22 @@ class Repository
end
def with_repo_branch_commit(start_repository, start_branch_name)
- tmp_ref = nil
return yield nil if start_repository.empty_repo?
- branch_commit =
- if start_repository == self
- commit(start_branch_name)
+ if start_repository == self
+ yield commit(start_branch_name)
+ else
+ sha = start_repository.commit(start_branch_name).sha
+
+ if branch_commit = commit(sha)
+ yield branch_commit
else
- sha = start_repository.find_branch(start_branch_name).target
- commit(sha) ||
- begin
- tmp_ref = fetch_ref(
- start_repository.path_to_repo,
- "#{Gitlab::Git::BRANCH_REF_PREFIX}#{start_branch_name}",
- "refs/tmp/#{SecureRandom.hex}/head"
- )
-
- commit(start_repository.commit(start_branch_name).sha)
- end
+ with_repo_tmp_commit(
+ start_repository, start_branch_name, sha) do |tmp_commit|
+ yield tmp_commit
+ end
end
-
- yield branch_commit
- ensure
- rugged.references.delete(tmp_ref) if tmp_ref
+ end
end
def add_remote(name, url)
@@ -1231,4 +1224,16 @@ class Repository
.commits_by_message(query, revision: ref, path: path, limit: limit, offset: offset)
.map { |c| commit(c) }
end
+
+ def with_repo_tmp_commit(start_repository, start_branch_name, sha)
+ tmp_ref = fetch_ref(
+ start_repository.path_to_repo,
+ "#{Gitlab::Git::BRANCH_REF_PREFIX}#{start_branch_name}",
+ "refs/tmp/#{SecureRandom.hex}/head"
+ )
+
+ yield commit(sha)
+ ensure
+ rugged.references.delete(tmp_ref) if tmp_ref
+ end
end
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 462e92b8b62..8d9a86d952b 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -923,13 +923,16 @@ describe Repository, models: true do
describe '#update_branch_with_hooks' do
let(:old_rev) { '0b4bc9a49b562e85de7cc9e834518ea6828729b9' } # git rev-parse feature
let(:new_rev) { 'a74ae73c1ccde9b974a70e82b901588071dc142a' } # commit whose parent is old_rev
+ let(:updating_ref) { 'refs/heads/feature' }
+ let(:target_project) { project }
+ let(:target_repository) { target_project.repository }
context 'when pre hooks were successful' do
before do
service = Gitlab::Git::HooksService.new
expect(Gitlab::Git::HooksService).to receive(:new).and_return(service)
expect(service).to receive(:execute)
- .with(committer, repository, old_rev, new_rev, 'refs/heads/feature')
+ .with(committer, target_repository, old_rev, new_rev, updating_ref)
.and_yield(service).and_return(true)
end
@@ -960,6 +963,37 @@ describe Repository, models: true do
expect(repository.find_branch('feature').dereferenced_target.id).to eq(new_rev)
end
end
+
+ context 'when target project does not have the commit' do
+ let(:target_project) { create(:project, :empty_repo) }
+ let(:old_rev) { Gitlab::Git::BLANK_SHA }
+ let(:new_rev) { project.commit('feature').sha }
+ let(:updating_ref) { 'refs/heads/master' }
+
+ it 'fetch_ref and create the branch' do
+ expect(target_project.repository).to receive(:fetch_ref)
+ .and_call_original
+
+ GitOperationService.new(committer, target_repository)
+ .with_branch(
+ 'master',
+ start_project: project,
+ start_branch_name: 'feature') { new_rev }
+
+ expect(target_repository.branch_names).to contain_exactly('master')
+ end
+ end
+
+ context 'when target project already has the commit' do
+ let(:target_project) { create(:project, :repository) }
+
+ it 'does not fetch_ref and just pass the commit' do
+ expect(target_repository).not_to receive(:fetch_ref)
+
+ GitOperationService.new(committer, target_repository)
+ .with_branch('feature', start_project: project) { new_rev }
+ end
+ end
end
context 'when temporary ref failed to be created from other project' do