Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-01-31 00:08:47 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-01-31 00:08:47 +0300
commitc8f773a8593926f4f2dec6f446a3b3e59e9c9909 (patch)
tree4e5ea1d3b861ff99015f6112da567de7873868aa /lib/gitlab/git
parent929b887e5391dea7cb53b88b77b9a35351c87d99 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/gitlab/git')
-rw-r--r--lib/gitlab/git/cross_repo_comparer.rb56
-rw-r--r--lib/gitlab/git/repository.rb33
2 files changed, 59 insertions, 30 deletions
diff --git a/lib/gitlab/git/cross_repo_comparer.rb b/lib/gitlab/git/cross_repo_comparer.rb
new file mode 100644
index 00000000000..3958373f7cb
--- /dev/null
+++ b/lib/gitlab/git/cross_repo_comparer.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Git
+ class CrossRepoComparer
+ attr_reader :source_repo, :target_repo
+
+ def initialize(source_repo, target_repo)
+ @source_repo = source_repo
+ @target_repo = target_repo
+ end
+
+ def compare(source_ref, target_ref, straight:)
+ ensuring_ref_in_source(target_ref) do |target_commit_id|
+ Gitlab::Git::Compare.new(
+ source_repo,
+ target_commit_id,
+ source_ref,
+ straight: straight
+ )
+ end
+ end
+
+ private
+
+ def ensuring_ref_in_source(ref, &blk)
+ return yield ref if source_repo == target_repo
+
+ # If the commit doesn't exist in the target, there's nothing we can do
+ commit_id = target_repo.commit(ref)&.sha
+ return unless commit_id
+
+ # The commit pointed to by ref may exist in the source even when they
+ # are different repositories. This is particularly true of close forks,
+ # but may also be the case if a temporary ref for this comparison has
+ # already been created in the past, and the result hasn't been GC'd yet.
+ return yield commit_id if source_repo.commit(commit_id)
+
+ # Worst case: the commit is not in the source repo so we need to fetch
+ # it. Use a temporary ref and clean up afterwards
+ with_commit_in_source_tmp(commit_id, &blk)
+ end
+
+ # Fetch the ref into source_repo from target_repo, using a temporary ref
+ # name that will be deleted once the method completes. This is a no-op if
+ # fetching the source branch fails
+ def with_commit_in_source_tmp(commit_id, &blk)
+ tmp_ref = "refs/tmp/#{SecureRandom.hex}"
+
+ yield commit_id if source_repo.fetch_source_branch!(target_repo, commit_id, tmp_ref)
+ ensure
+ source_repo.delete_refs(tmp_ref) # best-effort
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index ed3e7a1e39c..0120e3be14c 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -746,29 +746,9 @@ module Gitlab
end
def compare_source_branch(target_branch_name, source_repository, source_branch_name, straight:)
- reachable_ref =
- if source_repository == self
- source_branch_name
- else
- # If a tmp ref was created before for a separate repo comparison (forks),
- # we're able to short-circuit the tmp ref re-creation:
- # 1. Take the SHA from the source repo
- # 2. Read that in the current "target" repo
- # 3. If that SHA is still known (readable), it means GC hasn't
- # cleaned it up yet, so we can use it instead re-writing the tmp ref.
- source_commit_id = source_repository.commit(source_branch_name)&.sha
- commit(source_commit_id)&.sha if source_commit_id
- end
-
- return compare(target_branch_name, reachable_ref, straight: straight) if reachable_ref
-
- tmp_ref = "refs/tmp/#{SecureRandom.hex}"
-
- return unless fetch_source_branch!(source_repository, source_branch_name, tmp_ref)
-
- compare(target_branch_name, tmp_ref, straight: straight)
- ensure
- delete_refs(tmp_ref) if tmp_ref
+ CrossRepoComparer
+ .new(source_repository, self)
+ .compare(source_branch_name, target_branch_name, straight: straight)
end
def write_ref(ref_path, ref, old_ref: nil)
@@ -1046,13 +1026,6 @@ module Gitlab
private
- def compare(base_ref, head_ref, straight:)
- Gitlab::Git::Compare.new(self,
- base_ref,
- head_ref,
- straight: straight)
- end
-
def empty_diff_stats
Gitlab::Git::DiffStatsCollection.new([])
end