Introduce Repository#with_tmp_ref which we need
commits from the other repository. We'll cleanup the tmp ref after we're done with our business.
This commit is contained in:
parent
23032467d4
commit
8384d0d8d5
8 changed files with 54 additions and 29 deletions
|
@ -37,7 +37,8 @@ class Projects::CompareController < Projects::ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def define_diff_vars
|
def define_diff_vars
|
||||||
@compare = CompareService.new.execute(@project, @head_ref, @project, @start_ref)
|
@compare = CompareService.new(@project, @head_ref).
|
||||||
|
execute(@project, @start_ref)
|
||||||
|
|
||||||
if @compare
|
if @compare
|
||||||
@commits = @compare.commits
|
@commits = @compare.commits
|
||||||
|
|
|
@ -169,7 +169,8 @@ class MergeRequestDiff < ActiveRecord::Base
|
||||||
# When compare merge request versions we want diff A..B instead of A...B
|
# When compare merge request versions we want diff A..B instead of A...B
|
||||||
# so we handle cases when user does squash and rebase of the commits between versions.
|
# so we handle cases when user does squash and rebase of the commits between versions.
|
||||||
# For this reason we set straight to true by default.
|
# For this reason we set straight to true by default.
|
||||||
CompareService.new.execute(project, head_commit_sha, project, sha, straight: straight)
|
CompareService.new(project, head_commit_sha).
|
||||||
|
execute(project, sha, straight: straight)
|
||||||
end
|
end
|
||||||
|
|
||||||
def commits_count
|
def commits_count
|
||||||
|
|
|
@ -1099,6 +1099,21 @@ class Repository
|
||||||
Gitlab::Popen.popen(args, path_to_repo).first.lines.map(&:strip)
|
Gitlab::Popen.popen(args, path_to_repo).first.lines.map(&:strip)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def with_tmp_ref(source_repository, source_branch_name)
|
||||||
|
random_string = SecureRandom.hex
|
||||||
|
|
||||||
|
fetch_ref(
|
||||||
|
source_repository.path_to_repo,
|
||||||
|
"#{Gitlab::Git::BRANCH_REF_PREFIX}#{source_branch_name}",
|
||||||
|
"refs/tmp/#{random_string}/head"
|
||||||
|
)
|
||||||
|
|
||||||
|
yield
|
||||||
|
|
||||||
|
ensure
|
||||||
|
FileUtils.rm_rf("#{path_to_repo}/refs/tmp/#{random_string}")
|
||||||
|
end
|
||||||
|
|
||||||
def fetch_ref(source_path, source_ref, target_ref)
|
def fetch_ref(source_path, source_ref, target_ref)
|
||||||
args = %W(#{Gitlab.config.git.bin_path} fetch --no-tags -f #{source_path} #{source_ref}:#{target_ref})
|
args = %W(#{Gitlab.config.git.bin_path} fetch --no-tags -f #{source_path} #{source_ref}:#{target_ref})
|
||||||
Gitlab::Popen.popen(args, path_to_repo)
|
Gitlab::Popen.popen(args, path_to_repo)
|
||||||
|
|
|
@ -3,23 +3,29 @@ require 'securerandom'
|
||||||
# Compare 2 branches for one repo or between repositories
|
# Compare 2 branches for one repo or between repositories
|
||||||
# and return Gitlab::Git::Compare object that responds to commits and diffs
|
# and return Gitlab::Git::Compare object that responds to commits and diffs
|
||||||
class CompareService
|
class CompareService
|
||||||
def execute(source_project, source_branch, target_project, target_branch, straight: false)
|
attr_reader :source_project, :source_sha
|
||||||
source_commit = source_project.commit(source_branch)
|
|
||||||
return unless source_commit
|
|
||||||
|
|
||||||
source_sha = source_commit.sha
|
def initialize(new_source_project, source_branch)
|
||||||
|
@source_project = new_source_project
|
||||||
|
@source_sha = new_source_project.commit(source_branch).try(:sha)
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute(target_project, target_branch, straight: false)
|
||||||
|
return unless source_sha
|
||||||
|
|
||||||
# If compare with other project we need to fetch ref first
|
# If compare with other project we need to fetch ref first
|
||||||
unless target_project == source_project
|
if target_project == source_project
|
||||||
random_string = SecureRandom.hex
|
compare(target_project, target_branch, straight)
|
||||||
|
else
|
||||||
target_project.repository.fetch_ref(
|
target_project.repository.with_tmp_ref(source_project, source_branch) do
|
||||||
source_project.repository.path_to_repo,
|
compare(target_project, target_branch, straight)
|
||||||
"refs/heads/#{source_branch}",
|
end
|
||||||
"refs/tmp/#{random_string}/head"
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def compare(target_project, target_branch, straight)
|
||||||
raw_compare = Gitlab::Git::Compare.new(
|
raw_compare = Gitlab::Git::Compare.new(
|
||||||
target_project.repository.raw_repository,
|
target_project.repository.raw_repository,
|
||||||
target_branch,
|
target_branch,
|
||||||
|
|
|
@ -38,15 +38,14 @@ GitOperationService = Struct.new(:user, :repository) do
|
||||||
branch_name, source_branch_name, source_project)
|
branch_name, source_branch_name, source_project)
|
||||||
|
|
||||||
update_branch_with_hooks(branch_name) do |ref|
|
update_branch_with_hooks(branch_name) do |ref|
|
||||||
if repository.project != source_project
|
if repository.project == source_project
|
||||||
repository.fetch_ref(
|
yield(ref)
|
||||||
source_project.repository.path_to_repo,
|
else
|
||||||
"#{Gitlab::Git::BRANCH_REF_PREFIX}#{source_branch_name}",
|
repository.with_tmp_ref(
|
||||||
"#{Gitlab::Git::BRANCH_REF_PREFIX}#{branch_name}"
|
source_project.repository, source_branch_name) do
|
||||||
)
|
yield(ref)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
yield(ref)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,10 @@ module MergeRequests
|
||||||
messages = validate_branches(merge_request)
|
messages = validate_branches(merge_request)
|
||||||
return build_failed(merge_request, messages) unless messages.empty?
|
return build_failed(merge_request, messages) unless messages.empty?
|
||||||
|
|
||||||
compare = CompareService.new.execute(
|
compare = CompareService.new(
|
||||||
merge_request.source_project,
|
merge_request.source_project,
|
||||||
merge_request.source_branch,
|
merge_request.source_branch
|
||||||
|
).execute(
|
||||||
merge_request.target_project,
|
merge_request.target_project,
|
||||||
merge_request.target_branch,
|
merge_request.target_branch,
|
||||||
)
|
)
|
||||||
|
|
|
@ -33,13 +33,15 @@ class EmailsOnPushWorker
|
||||||
reverse_compare = false
|
reverse_compare = false
|
||||||
|
|
||||||
if action == :push
|
if action == :push
|
||||||
compare = CompareService.new.execute(project, after_sha, project, before_sha)
|
compare = CompareService.new(project, after_sha).
|
||||||
|
execute(project, before_sha)
|
||||||
diff_refs = compare.diff_refs
|
diff_refs = compare.diff_refs
|
||||||
|
|
||||||
return false if compare.same
|
return false if compare.same
|
||||||
|
|
||||||
if compare.commits.empty?
|
if compare.commits.empty?
|
||||||
compare = CompareService.new.execute(project, before_sha, project, after_sha)
|
compare = CompareService.new(project, before_sha).
|
||||||
|
execute(project, after_sha)
|
||||||
diff_refs = compare.diff_refs
|
diff_refs = compare.diff_refs
|
||||||
|
|
||||||
reverse_compare = true
|
reverse_compare = true
|
||||||
|
|
|
@ -3,17 +3,17 @@ require 'spec_helper'
|
||||||
describe CompareService, services: true do
|
describe CompareService, services: true do
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
let(:service) { described_class.new }
|
let(:service) { described_class.new(project, 'feature') }
|
||||||
|
|
||||||
describe '#execute' do
|
describe '#execute' do
|
||||||
context 'compare with base, like feature...fix' do
|
context 'compare with base, like feature...fix' do
|
||||||
subject { service.execute(project, 'feature', project, 'fix', straight: false) }
|
subject { service.execute(project, 'fix', straight: false) }
|
||||||
|
|
||||||
it { expect(subject.diffs.size).to eq(1) }
|
it { expect(subject.diffs.size).to eq(1) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'straight compare, like feature..fix' do
|
context 'straight compare, like feature..fix' do
|
||||||
subject { service.execute(project, 'feature', project, 'fix', straight: true) }
|
subject { service.execute(project, 'fix', straight: true) }
|
||||||
|
|
||||||
it { expect(subject.diffs.size).to eq(3) }
|
it { expect(subject.diffs.size).to eq(3) }
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue