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>2022-12-15 21:09:34 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-12-15 21:09:34 +0300
commita84aefe0bb8fc2ad47ab67cb4ddcfbb7aecfbd5e (patch)
treedfcd00dc9603a8c652211c6066ceae0c97df1a7f /app/models/projects
parent16cdacff02fbf0069182e090df2eeaa754007957 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/models/projects')
-rw-r--r--app/models/projects/forks/divergence_counts.rb41
1 files changed, 32 insertions, 9 deletions
diff --git a/app/models/projects/forks/divergence_counts.rb b/app/models/projects/forks/divergence_counts.rb
index 0831d9cbc7e..7d630b00083 100644
--- a/app/models/projects/forks/divergence_counts.rb
+++ b/app/models/projects/forks/divergence_counts.rb
@@ -4,6 +4,7 @@ module Projects
module Forks
# Class for calculating the divergence of a fork with the source project
class DivergenceCounts
+ LATEST_COMMITS_COUNT = 10
EXPIRATION_TIME = 8.hours
def initialize(project, ref)
@@ -14,9 +15,9 @@ module Projects
end
def counts
- ahead, behind = calculate_divergence_counts
+ ahead, behind = divergence_counts
- { ahead: ahead.to_i, behind: behind.to_i }
+ { ahead: ahead, behind: behind }
end
private
@@ -27,23 +28,45 @@ module Projects
@cache_key ||= ['project_forks', project.id, ref, 'divergence_counts']
end
- def calculate_divergence_counts
+ def divergence_counts
fork_sha = fork_repo.commit(ref).sha
source_sha = source_repo.commit.sha
cached_source_sha, cached_fork_sha, counts = Rails.cache.read(cache_key)
- return counts if counts.present? && cached_source_sha == source_sha && cached_fork_sha == fork_sha
+ return counts if cached_source_sha == source_sha && cached_fork_sha == fork_sha
- counts =
- Gitlab::Git::CrossRepo.new(fork_repo, source_repo)
- .execute(source_sha) do |cross_repo_sha|
- fork_repo.count_commits_between(fork_sha, cross_repo_sha, left_right: true)
- end
+ counts = calculate_divergence_counts(fork_sha, source_sha)
Rails.cache.write(cache_key, [source_sha, fork_sha, counts], expires_in: EXPIRATION_TIME)
counts
end
+
+ def calculate_divergence_counts(fork_sha, source_sha)
+ # If the upstream latest commit exists in the fork repo, then
+ # it's possible to calculate divergence counts within the fork repository.
+ return fork_repo.diverging_commit_count(fork_sha, source_sha) if fork_repo.commit(source_sha)
+
+ # Otherwise, we need to find a commit that exists both in the fork and upstream
+ # in order to use this commit as a base for calculating divergence counts.
+ # Considering the fact that a user usually creates a fork to contribute to the upstream,
+ # it is expected that they have a limited number of commits ahead of upstream.
+ # Let's take the latest N commits and check their existence upstream.
+ last_commits_shas = fork_repo.commits(ref, limit: LATEST_COMMITS_COUNT).map(&:sha)
+ existence_hash = source_repo.check_objects_exist(last_commits_shas)
+ first_matched_commit_sha = last_commits_shas.find { |sha| existence_hash[sha] }
+
+ # If we can't find such a commit, we return early and tell the user that the branches
+ # have diverged and action is required.
+ return unless first_matched_commit_sha
+
+ # Otherwise, we use upstream to calculate divergence counts from the matched commit
+ ahead, behind = source_repo.diverging_commit_count(first_matched_commit_sha, source_sha)
+ # And add the number of commits a fork is ahead of the first matched commit
+ ahead += last_commits_shas.index(first_matched_commit_sha)
+
+ [ahead, behind]
+ end
end
end
end