summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorLuke Duncalfe <lduncalfe@eml.cc>2019-03-14 17:20:40 +1300
committerLuke Duncalfe <lduncalfe@eml.cc>2019-03-22 10:26:15 +1300
commit38bf176c3cf7b26233ad78103a04546445348983 (patch)
tree9a1d9945227991195230394b67fff338c2d28d4d /app
parentdd43abecf93035d36b649c75c05143cc08db1566 (diff)
downloadgitlab-ce-38bf176c3cf7b26233ad78103a04546445348983.tar.gz
Enrich commits with full data in CommitCollection
Allow incomplete commit records to load their full data from gitaly. Commits can be based on a Hash of data retrieved from PostgreSQL, and this data can be intentionally incomplete in order to save space. A new method #gitaly? has been added to Gitlab::Git::Commit, which returns true if the underlying data source of the Commit is a Gitaly::GitCommit. CommitCollection now has a method #enrich which replaces non-gitaly commits in place with commits from gitaly. CommitCollection#without_merge_commits has been updated to call this method, as in order to determine a merge commit we need to have parent data. Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/58805
Diffstat (limited to 'app')
-rw-r--r--app/models/commit_collection.rb31
1 files changed, 30 insertions, 1 deletions
diff --git a/app/models/commit_collection.rb b/app/models/commit_collection.rb
index a9a2e9c81eb..f4e64abf362 100644
--- a/app/models/commit_collection.rb
+++ b/app/models/commit_collection.rb
@@ -28,10 +28,39 @@ class CommitCollection
def without_merge_commits
strong_memoize(:without_merge_commits) do
- commits.reject(&:merge_commit?)
+ # `#enrich!` the collection to ensure all commits contain
+ # the necessary parent data
+ enrich!.commits.reject(&:merge_commit?)
end
end
+ def unenriched
+ commits.reject(&:gitaly_commit?)
+ end
+
+ def fully_enriched?
+ unenriched.empty?
+ end
+
+ # Batch load any commits that are not backed by full gitaly data, and
+ # replace them in the collection.
+ def enrich!
+ return self if fully_enriched?
+
+ # Batch load full Commits from the repository
+ # and map to a Hash of id => Commit
+ replacements = Hash[unenriched.map do |c|
+ [c.id, Commit.lazy(project, c.id)]
+ end.compact]
+
+ # Replace the commits, keeping the same order
+ @commits = @commits.map do |c|
+ replacements.fetch(c.id, c)
+ end
+
+ self
+ end
+
# Sets the pipeline status for every commit.
#
# Setting this status ahead of time removes the need for running a query for