Class: CommitCollection
- Inherits:
-
Object
- Object
- CommitCollection
- Includes:
- Enumerable, Gitlab::Utils::StrongMemoize
- Defined in:
- app/models/commit_collection.rb
Overview
A collection of Commit instances for a specific container and Git reference.
Instance Attribute Summary collapse
-
#commits ⇒ Object
readonly
Returns the value of attribute commits.
-
#container ⇒ Object
readonly
Returns the value of attribute container.
-
#ref ⇒ Object
readonly
Returns the value of attribute ref.
Instance Method Summary collapse
- #committers ⇒ Object
- #each(&block) ⇒ Object
-
#enrich! ⇒ Object
Batch load any commits that are not backed by full gitaly data, and replace them in the collection.
- #fully_enriched? ⇒ Boolean
-
#initialize(container, commits, ref = nil) ⇒ CommitCollection
constructor
container - The object the commits belong to.
-
#method_missing(message, *args, &block) ⇒ Object
rubocop:disable GitlabSecurity/PublicSend.
- #respond_to_missing?(message, inc_private = false) ⇒ Boolean
- #unenriched ⇒ Object
-
#with_latest_pipeline(ref = nil) ⇒ Object
Returns the collection with the latest pipeline for every commit pre-set.
-
#with_markdown_cache ⇒ Object
Returns the collection with markdown fields preloaded.
- #without_merge_commits ⇒ Object
Methods included from Gitlab::Utils::StrongMemoize
#clear_memoization, #strong_memoize, #strong_memoized?
Constructor Details
#initialize(container, commits, ref = nil) ⇒ CommitCollection
container - The object the commits belong to. commits - The Commit instances to store. ref - The name of the ref (e.g. “master”).
16 17 18 19 20 |
# File 'app/models/commit_collection.rb', line 16 def initialize(container, commits, ref = nil) @container = container @commits = commits @ref = ref end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(message, *args, &block) ⇒ Object
rubocop:disable GitlabSecurity/PublicSend
113 114 115 |
# File 'app/models/commit_collection.rb', line 113 def method_missing(, *args, &block) commits.public_send(, *args, &block) end |
Instance Attribute Details
#commits ⇒ Object (readonly)
Returns the value of attribute commits
8 9 10 |
# File 'app/models/commit_collection.rb', line 8 def commits @commits end |
#container ⇒ Object (readonly)
Returns the value of attribute container
8 9 10 |
# File 'app/models/commit_collection.rb', line 8 def container @container end |
#ref ⇒ Object (readonly)
Returns the value of attribute ref
8 9 10 |
# File 'app/models/commit_collection.rb', line 8 def ref @ref end |
Instance Method Details
#committers ⇒ Object
26 27 28 29 30 |
# File 'app/models/commit_collection.rb', line 26 def committers emails = without_merge_commits.map(&:committer_email).uniq User.by_any_email(emails) end |
#each(&block) ⇒ Object
22 23 24 |
# File 'app/models/commit_collection.rb', line 22 def each(&block) commits.each(&block) end |
#enrich! ⇒ Object
Batch load any commits that are not backed by full gitaly data, and replace them in the collection.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'app/models/commit_collection.rb', line 80 def enrich! # A container is needed in order to fetch data from gitaly. Containers # can be absent from commits in certain rare situations (like when # viewing a MR of a deleted fork). In these cases, assume that the # enriched data is not needed. return self if container.blank? || 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(container, c.id)] end.compact] # Replace the commits, keeping the same order @commits = @commits.map do |original_commit| # Return the original instance: if it didn't need to be batchloaded, it was # already enriched. batch_loaded_commit = replacements.fetch(original_commit.id, original_commit) # If batch loading the commit failed, fall back to the original commit. # We need to explicitly check `.nil?` since otherwise a `BatchLoader` instance # that looks like `nil` is returned. batch_loaded_commit.nil? ? original_commit : batch_loaded_commit end self end |
#fully_enriched? ⇒ Boolean
74 75 76 |
# File 'app/models/commit_collection.rb', line 74 def fully_enriched? unenriched.empty? end |
#respond_to_missing?(message, inc_private = false) ⇒ Boolean
108 109 110 |
# File 'app/models/commit_collection.rb', line 108 def respond_to_missing?(, inc_private = false) commits.respond_to?(, inc_private) end |
#unenriched ⇒ Object
70 71 72 |
# File 'app/models/commit_collection.rb', line 70 def unenriched commits.reject(&:gitaly_commit?) end |
#with_latest_pipeline(ref = nil) ⇒ Object
Returns the collection with the latest pipeline for every commit pre-set.
Setting the pipeline for each commit ahead of time removes the need for running a query for every commit we're displaying.
44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'app/models/commit_collection.rb', line 44 def with_latest_pipeline(ref = nil) return self unless project pipelines = project.ci_pipelines.latest_pipeline_per_commit(map(&:id), ref) each do |commit| pipeline = pipelines[commit.id] pipeline&.number_of_warnings # preload number of warnings commit.set_latest_pipeline_for_ref(ref, pipeline) end self end |
#with_markdown_cache ⇒ Object
Returns the collection with markdown fields preloaded.
Get the markdown cache from redis using pipeline to prevent n+1 requests when rendering the markdown of an attribute (e.g. title, full_title, description).
64 65 66 67 68 |
# File 'app/models/commit_collection.rb', line 64 def with_markdown_cache Commit.preload_markdown_cache!(commits) self end |
#without_merge_commits ⇒ Object
32 33 34 35 36 37 38 |
# File 'app/models/commit_collection.rb', line 32 def without_merge_commits strong_memoize(:without_merge_commits) do # `#enrich!` the collection to ensure all commits contain # the necessary parent data enrich!.commits.reject(&:merge_commit?) end end |