Class: Commit

Inherits:
Object
  • Object
show all
Extended by:
ActiveModel::Naming, Gitlab::Cache::RequestCache, Gitlab::Utils::Override
Includes:
ActiveModel::Conversion, ActsAsPaginatedDiff, CacheMarkdownField, Gitlab::Utils::StrongMemoize, Mentionable, Noteable, Participable, Presentable, Referable, StaticModel
Defined in:
app/models/commit.rb

Constant Summary collapse

MIN_SHA_LENGTH =
Gitlab::Git::Commit::MIN_SHA_LENGTH
MAX_SHA_LENGTH =
Gitlab::Git::Commit::MAX_SHA_LENGTH
COMMIT_SHA_PATTERN =
Gitlab::Git::Commit::SHA_PATTERN
EXACT_COMMIT_SHA_PATTERN =
/\A#{COMMIT_SHA_PATTERN}\z/
/(patch)/
DEFAULT_MAX_DIFF_LINES_SETTING =
50_000
DEFAULT_MAX_DIFF_FILES_SETTING =
1_000
MAX_DIFF_LINES_SETTING_UPPER_BOUND =
100_000
MAX_DIFF_FILES_SETTING_UPPER_BOUND =
3_000
DIFF_SAFE_LIMIT_FACTOR =
10
DRAFT_REGEX =

We are continuing to support ‘(fixup!|squash!)` here as it is the prefix

added by `git commit --fixup` which is used by some community members.
https://gitlab.com/gitlab-org/gitlab/-/issues/342937#note_892065311
/\A\s*#{Gitlab::Regex.merge_request_draft}|(fixup!|squash!)\s/

Constants included from CacheMarkdownField

CacheMarkdownField::INVALIDATED_BY

Constants included from Noteable

Noteable::MAX_NOTES_LIMIT

Instance Attribute Summary collapse

Attributes included from Gitlab::Cache::RequestCache

#request_cache_key_block

Attributes included from CacheMarkdownField

#skip_markdown_cache_validation

Attributes included from Noteable

#system_note_timestamp

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Gitlab::Cache::RequestCache

extended, request_cache, request_cache_key

Methods included from Gitlab::Utils::Override

extended, extensions, included, method_added, override, prepended, queue_verification, verify!

Methods included from CacheMarkdownField

#attribute_invalidated?, #banzai_render_context, #cached_html_for, #cached_html_up_to_date?, #can_cache_field?, #invalidated_markdown_cache?, #latest_cached_markdown_version, #local_version, #mentionable_attributes_changed?, #mentioned_filtered_user_ids_for, #parent_user, #refresh_markdown_cache, #refresh_markdown_cache!, #rendered_field_content, #skip_project_check?, #store_mentions!, #updated_cached_html_for

Methods included from ActsAsPaginatedDiff

#diffs_in_batch

Methods included from Presentable

#present

Methods included from StaticModel

#[], #destroyed?, #new_record?, #to_param

Methods included from Referable

#referable_inspect, #to_reference_base

Methods included from Mentionable

#all_references, #create_cross_references!, #create_new_cross_references!, #directly_addressed_users, #extractors, #gfm_reference, #local_reference, #matches_cross_reference_regex?, #mentioned_users, #referenced_group_users, #referenced_groups, #referenced_mentionables, #referenced_project_users, #referenced_projects, #referenced_users

Methods included from Participable

#participant?, #participants, #visible_participants

Methods included from Noteable

#after_note_created, #after_note_destroyed, #base_class_name, #capped_notes_count, #commenters, #creatable_note_email_address, #discussion_ids_relation, #discussion_root_note_ids, #discussions, #discussions_can_be_resolved_by?, #discussions_rendered_on_frontend?, #discussions_resolvable?, #discussions_resolved?, #discussions_to_be_resolved, #grouped_diff_discussions, #has_any_diff_note_positions?, #human_class_name, #lockable?, #noteable_target_type_name, #preloads_discussion_diff_highlighting?, #real_time_notes_enabled?, #resolvable_discussions, #supports_creating_notes_by_email?, #supports_discussions?, #supports_replying_to_individual_notes?, #supports_resolvable_notes?, #supports_suggestion?

Constructor Details

#initialize(raw_commit, container) ⇒ Commit

Returns a new instance of Commit.



161
162
163
164
165
166
# File 'app/models/commit.rb', line 161

def initialize(raw_commit, container)
  raise "Nil as raw commit passed" unless raw_commit

  @raw = raw_commit
  @container = container
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object



348
349
350
# File 'app/models/commit.rb', line 348

def method_missing(method, *args, &block)
  @raw.__send__(method, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
end

Instance Attribute Details

#containerObject (readonly)

Returns the value of attribute container.



26
27
28
# File 'app/models/commit.rb', line 26

def container
  @container
end

#rawObject

Returns the value of attribute raw.



159
160
161
# File 'app/models/commit.rb', line 159

def raw
  @raw
end

#redacted_description_htmlObject

Returns the value of attribute redacted_description_html.



23
24
25
# File 'app/models/commit.rb', line 23

def redacted_description_html
  @redacted_description_html
end

#redacted_full_title_htmlObject

Returns the value of attribute redacted_full_title_html.



25
26
27
# File 'app/models/commit.rb', line 25

def redacted_full_title_html
  @redacted_full_title_html
end

#redacted_title_htmlObject

Returns the value of attribute redacted_title_html.



24
25
26
# File 'app/models/commit.rb', line 24

def redacted_title_html
  @redacted_title_html
end

Class Method Details

.build_from_sidekiq_hash(project, hash) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'app/models/commit.rb', line 138

def build_from_sidekiq_hash(project, hash)
  hash = hash.dup
  date_suffix = '_date'

  # When processing Sidekiq payloads various timestamps are stored as Strings.
  # Commit in turn expects Time-like instances upon input, so we have to
  # manually parse these values.
  hash.each do |key, value|
    if key.to_s.end_with?(date_suffix) && value.is_a?(String)
      hash[key] = Time.zone.parse(value)
    end
  end

  from_hash(hash, project)
end

.decorate(commits, container) ⇒ Object



53
54
55
56
57
58
59
60
61
# File 'app/models/commit.rb', line 53

def decorate(commits, container)
  commits.map do |commit|
    if commit.is_a?(Commit)
      commit
    else
      self.new(commit, container)
    end
  end
end

.diff_line_count(diffs) ⇒ Object

Calculate number of lines to render for diffs



64
65
66
# File 'app/models/commit.rb', line 64

def diff_line_count(diffs)
  diffs.reduce(0) { |sum, d| sum + Gitlab::Git::Util.count_lines(d.diff) }
end

.diff_max_filesObject



88
89
90
# File 'app/models/commit.rb', line 88

def diff_max_files
  Gitlab::CurrentSettings.diff_max_files
end

.diff_max_linesObject



92
93
94
# File 'app/models/commit.rb', line 92

def diff_max_lines
  Gitlab::CurrentSettings.diff_max_lines
end

.diff_safe_max_filesObject



103
104
105
# File 'app/models/commit.rb', line 103

def diff_safe_max_files
  diff_max_files / DIFF_SAFE_LIMIT_FACTOR
end

.diff_safe_max_linesObject



107
108
109
# File 'app/models/commit.rb', line 107

def diff_safe_max_lines
  diff_max_lines / DIFF_SAFE_LIMIT_FACTOR
end

.from_hash(hash, container) ⇒ Object



111
112
113
114
# File 'app/models/commit.rb', line 111

def from_hash(hash, container)
  raw_commit = Gitlab::Git::Commit.new(container.repository.raw, hash)
  new(raw_commit, container)
end

.lazy(container, oid) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'app/models/commit.rb', line 120

def lazy(container, oid)
  BatchLoader.for({ container: container, oid: oid }).batch do |items, loader|
    items_by_container = items.group_by { |i| i[:container] }

    items_by_container.each do |container, commit_ids|
      oids = commit_ids.map { |i| i[:oid] }

      container.repository.commits_by(oids: oids).each do |commit|
        loader.call({ container: commit.container, oid: commit.id }, commit) if commit
      end
    end
  end
end


212
213
214
215
216
# File 'app/models/commit.rb', line 212

def self.link_reference_pattern
  @link_reference_pattern ||=
    compose_link_reference_pattern('commit',
      /(?<commit>#{COMMIT_SHA_PATTERN})?(\.(?<extension>#{LINK_EXTENSION_PATTERN}))?/o)
end

.max_diff_optionsObject



96
97
98
99
100
101
# File 'app/models/commit.rb', line 96

def max_diff_options
  {
    max_files: diff_max_files,
    max_lines: diff_max_lines
  }
end

.order_by(collection:, order_by:, sort:) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'app/models/commit.rb', line 68

def order_by(collection:, order_by:, sort:)
  return collection unless %w[email name commits].include?(order_by)
  return collection unless %w[asc desc].include?(sort)

  collection.sort do |a, b|
    operands = [a, b].tap { |o| o.reverse! if sort == 'desc' }

    attr1 = operands.first.public_send(order_by) # rubocop:disable GitlabSecurity/PublicSend
    attr2 = operands.second.public_send(order_by) # rubocop:disable GitlabSecurity/PublicSend

    # use case insensitive comparison for string values
    order_by.in?(%w[email name]) ? attr1.casecmp(attr2) : attr1 <=> attr2
  end
end

.parent_classObject



134
135
136
# File 'app/models/commit.rb', line 134

def parent_class
  ::Project
end

.reference_patternObject

Pattern used to extract commit references from text

This pattern supports cross-project references.



205
206
207
208
209
210
# File 'app/models/commit.rb', line 205

def self.reference_pattern
  @reference_pattern ||= %r{
    (?:#{Project.reference_pattern}#{reference_prefix})?
    (?<commit>#{COMMIT_SHA_PATTERN})
  }x
end

.reference_prefixObject



194
195
196
# File 'app/models/commit.rb', line 194

def self.reference_prefix
  '@'
end

.reference_valid?(reference) ⇒ Boolean

Returns:

  • (Boolean)


198
199
200
# File 'app/models/commit.rb', line 198

def self.reference_valid?(reference)
  !!(reference =~ EXACT_COMMIT_SHA_PATTERN)
end

.truncate_sha(sha) ⇒ Object

Truncate sha to 8 characters



84
85
86
# File 'app/models/commit.rb', line 84

def truncate_sha(sha)
  sha[0..MIN_SHA_LENGTH]
end

.underscoreObject



154
155
156
# File 'app/models/commit.rb', line 154

def underscore
  'commit'
end

.valid_hash?(key) ⇒ Boolean

Returns:

  • (Boolean)


116
117
118
# File 'app/models/commit.rb', line 116

def valid_hash?(key)
  !!(EXACT_COMMIT_SHA_PATTERN =~ key)
end

Instance Method Details

#==(other) ⇒ Object



190
191
192
# File 'app/models/commit.rb', line 190

def ==(other)
  other.is_a?(self.class) && raw == other.raw
end

#authorObject



311
312
313
314
315
# File 'app/models/commit.rb', line 311

def author
  strong_memoize(:author) do
    lazy_author&.itself
  end
end

#author_full_textObject



254
255
256
257
258
259
260
# File 'app/models/commit.rb', line 254

def author_full_text
  return unless author_name && author_email

  strong_memoize(:author_full_text) do
    "#{author_name} <#{author_email}>"
  end
end

#branches_containing(limit: 0, exclude_tipped: false) ⇒ Object



588
589
590
591
592
593
594
595
596
# File 'app/models/commit.rb', line 588

def branches_containing(limit: 0, exclude_tipped: false)
  # WARNING: This argument can be confusing, if there is a limit.
  # for example set the limit to 5 and in the 5 out a total of 25 refs there is 2 tipped refs,
  # then the method will only 3 refs, even though there is more.
  excluded = exclude_tipped ? tipping_branches : []

  refs = repository.branch_names_contains(id, limit: limit) || []
  refs - excluded
end

#broadcast_notes_changedObject



557
558
559
560
561
# File 'app/models/commit.rb', line 557

def broadcast_notes_changed
  super

  broadcast_notes_changed_for_related_mrs
end

#cache_keyObject



553
554
555
# File 'app/models/commit.rb', line 553

def cache_key
  "commit:#{sha}"
end

#change_type_title(user) ⇒ Object



478
479
480
# File 'app/models/commit.rb', line 478

def change_type_title(user)
  merged_merge_request?(user) ? 'merge request' : 'commit'
end

#cherry_pick_branch_nameObject



412
413
414
# File 'app/models/commit.rb', line 412

def cherry_pick_branch_name
  repository.next_branch("cherry-pick-#{short_id}", mild: true)
end

#cherry_pick_description(user) ⇒ Object



416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
# File 'app/models/commit.rb', line 416

def cherry_pick_description(user)
  message_body = ["(cherry picked from commit #{sha})"]

  if merged_merge_request?(user)
    commits_in_merge_request = merged_merge_request(user).commits

    if commits_in_merge_request.present?
      message_body << ""

      commits_in_merge_request.reverse_each do |commit_in_merge|
        message_body << "#{commit_in_merge.short_id} #{commit_in_merge.title}"
      end
    end
  end

  message_body.join("\n")
end

#cherry_pick_message(user) ⇒ Object



434
435
436
# File 'app/models/commit.rb', line 434

def cherry_pick_message(user)
  %(#{message}\n\n#{cherry_pick_description(user)})
end

#committer(confirmed: true) ⇒ Object



318
319
320
# File 'app/models/commit.rb', line 318

def committer(confirmed: true)
  @committer ||= User.find_by_any_email(committer_email, confirmed: confirmed)
end

#descriptionObject

Returns full commit message if title is truncated (greater than 99 characters) otherwise returns commit message without first line



264
265
266
267
268
269
# File 'app/models/commit.rb', line 264

def description
  return safe_message if full_title.length >= 100
  return no_commit_message if safe_message.blank?

  safe_message.split("\n", 2)[1].try(:chomp)
end

#description?Boolean

Returns:

  • (Boolean)


271
272
273
# File 'app/models/commit.rb', line 271

def description?
  description.present?
end

#diff_line_countObject



226
227
228
229
# File 'app/models/commit.rb', line 226

def diff_line_count
  @diff_line_count ||= Commit.diff_line_count(raw_diffs)
  @diff_line_count
end

#diff_refsObject



360
361
362
363
364
365
# File 'app/models/commit.rb', line 360

def diff_refs
  Gitlab::Diff::DiffRefs.new(
    base_sha: self.parent_id || Gitlab::Git::BLANK_SHA,
    head_sha: self.sha
  )
end

#diffs(diff_options = {}) ⇒ Object



516
517
518
# File 'app/models/commit.rb', line 516

def diffs(diff_options = {})
  Gitlab::Diff::FileCollection::Commit.new(self, diff_options: diff_options)
end

#discussion_notesObject



340
341
342
# File 'app/models/commit.rb', line 340

def discussion_notes
  notes.non_diff_notes
end

#draft?Boolean Also known as: work_in_progress?

Returns:

  • (Boolean)


544
545
546
# File 'app/models/commit.rb', line 544

def draft?
  !!(title =~ DRAFT_REGEX)
end

#full_titleObject

Returns the full commits title



245
246
247
248
249
250
251
252
# File 'app/models/commit.rb', line 245

def full_title
  @full_title ||=
    if safe_message.blank?
      no_commit_message
    else
      safe_message.split(/[\r\n]/, 2).first
    end
end

#gpg_commitObject



404
405
406
# File 'app/models/commit.rb', line 404

def gpg_commit
  @gpg_commit ||= Gitlab::Gpg::Commit.new(self)
end

#has_been_reverted?(current_user, notes_association = nil) ⇒ Boolean

Returns:

  • (Boolean)


467
468
469
470
471
472
473
474
475
476
# File 'app/models/commit.rb', line 467

def has_been_reverted?(current_user, notes_association = nil)
  ext = Gitlab::ReferenceExtractor.new(project, current_user)
  notes_association ||= notes_with_associations

  notes_association.system.each do |note|
    note.all_references(current_user, extractor: ext)
  end

  ext.commits.any? { |commit_ref| commit_ref.reverts_commit?(self, current_user) }
end

#has_signature?Boolean

Returns:

  • (Boolean)


367
368
369
# File 'app/models/commit.rb', line 367

def has_signature?
  signature_type && signature_type != :NONE
end

#hook_attrs(with_changed_files: false) ⇒ Object



279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# File 'app/models/commit.rb', line 279

def hook_attrs(with_changed_files: false)
  data = {
    id: id,
    message: safe_message,
    title: title,
    timestamp: timestamp,
    url: Gitlab::UrlBuilder.build(self),
    author: {
      name: author_name,
      email: author_email
    }
  }

  if with_changed_files
    data.merge!(repo_changes)
  end

  data
end

#idObject



182
183
184
# File 'app/models/commit.rb', line 182

def id
  raw.id
end

#lazy_authorObject



299
300
301
302
303
304
305
306
307
308
309
# File 'app/models/commit.rb', line 299

def lazy_author
  BatchLoader.for(author_email.downcase).batch do |emails, loader|
    users = User.by_any_email(emails, confirmed: true).includes(:emails)

    emails.each do |email|
      user = users.find { |u| u.any_email?(email) }

      loader.call(email, user)
    end
  end
end

#merge_commit?Boolean

Returns:

  • (Boolean)


454
455
456
# File 'app/models/commit.rb', line 454

def merge_commit?
  parent_ids.size > 1
end

#merged_merge_request(current_user) ⇒ Object



458
459
460
461
462
463
464
465
# File 'app/models/commit.rb', line 458

def merged_merge_request(current_user)
  # Memoize with per-user access check
  @merged_merge_request_hash ||= Hash.new do |hash, user|
    hash[user] = merged_merge_request_no_cache(user)
  end

  @merged_merge_request_hash[current_user]
end

#merged_merge_request?(user) ⇒ Boolean

Returns:

  • (Boolean)


549
550
551
# File 'app/models/commit.rb', line 549

def merged_merge_request?(user)
  !!merged_merge_request(user)
end

#notesObject



332
333
334
# File 'app/models/commit.rb', line 332

def notes
  container.notes.for_commit_id(self.id)
end

#notes_with_associationsObject



344
345
346
# File 'app/models/commit.rb', line 344

def notes_with_associations
  notes.includes(:author, :award_emoji)
end

#parentObject



326
327
328
329
330
# File 'app/models/commit.rb', line 326

def parent
  strong_memoize(:parent) do
    container.commit_by(oid: self.parent_id) if self.parent_id
  end
end

#parentsObject



322
323
324
# File 'app/models/commit.rb', line 322

def parents
  @parents ||= parent_ids.map { |oid| Commit.lazy(container, oid) }
end

#persisted?Boolean

Returns:

  • (Boolean)


520
521
522
# File 'app/models/commit.rb', line 520

def persisted?
  true
end

#project_idObject



186
187
188
# File 'app/models/commit.rb', line 186

def project_id
  project&.id
end

#raw_commit_from_rugged?Boolean

Returns:

  • (Boolean)


400
401
402
# File 'app/models/commit.rb', line 400

def raw_commit_from_rugged?
  @raw.raw_commit.is_a?(Rugged::Commit)
end

#raw_deltasObject



512
513
514
# File 'app/models/commit.rb', line 512

def raw_deltas
  @deltas ||= raw.deltas
end

#raw_diffsObject



508
509
510
# File 'app/models/commit.rb', line 508

def raw_diffs(...)
  raw.diffs(...)
end

#raw_signature_typeObject



371
372
373
374
375
376
377
378
379
380
381
# File 'app/models/commit.rb', line 371

def raw_signature_type
  strong_memoize(:raw_signature_type) do
    next unless @raw.instance_of?(Gitlab::Git::Commit)

    if raw_commit_from_rugged? && gpg_commit.signature_text.present?
      :PGP
    elsif defined? @raw.raw_commit.signature_type
      @raw.raw_commit.signature_type
    end
  end
end

#readable_by?(user) ⇒ Boolean

Returns:

  • (Boolean)


563
564
565
# File 'app/models/commit.rb', line 563

def readable_by?(user)
  Ability.allowed?(user, :read_commit, self)
end


222
223
224
# File 'app/models/commit.rb', line 222

def reference_link_text(from = nil, full: false)
  commit_reference(from, short_id, full: full)
end

#respond_to_missing?(method, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


352
353
354
# File 'app/models/commit.rb', line 352

def respond_to_missing?(method, include_private = false)
  @raw.respond_to?(method, include_private) || super
end

#revert_branch_nameObject



408
409
410
# File 'app/models/commit.rb', line 408

def revert_branch_name
  "revert-#{short_id}"
end

#revert_description(user) ⇒ Object



438
439
440
441
442
443
444
# File 'app/models/commit.rb', line 438

def revert_description(user)
  if merged_merge_request?(user)
    "This reverts merge request #{merged_merge_request(user).to_reference}"
  else
    "This reverts commit #{sha}"
  end
end

#revert_message(user) ⇒ Object



446
447
448
# File 'app/models/commit.rb', line 446

def revert_message(user)
  %(Revert "#{title.strip}"\n\n#{revert_description(user)})
end

#reverts_commit?(commit, user) ⇒ Boolean

Returns:

  • (Boolean)


450
451
452
# File 'app/models/commit.rb', line 450

def reverts_commit?(commit, user)
  description? && description.include?(commit.revert_description(user))
end

#short_idObject



356
357
358
# File 'app/models/commit.rb', line 356

def short_id
  @raw.short_id(MIN_SHA_LENGTH)
end

#signatureObject



387
388
389
390
391
392
393
394
395
396
397
398
# File 'app/models/commit.rb', line 387

def signature
  strong_memoize(:signature) do
    case signature_type
    when :PGP
      gpg_commit.signature
    when :X509
      Gitlab::X509::Commit.new(self).signature
    when :SSH
      Gitlab::Ssh::Commit.new(self).signature
    end
  end
end

#signature_typeObject



383
384
385
# File 'app/models/commit.rb', line 383

def signature_type
  @signature_type ||= raw_signature_type || :NONE
end

#tags_containing(limit: 0, exclude_tipped: false) ⇒ Object



598
599
600
601
602
603
604
605
606
# File 'app/models/commit.rb', line 598

def tags_containing(limit: 0, exclude_tipped: false)
  # WARNING: This argument can be confusing, if there is a limit.
  # for example set the limit to 5 and in the 5 out a total of 25 refs there is 2 tipped refs,
  # then the method will only 3 refs, even though there is more.
  excluded = exclude_tipped ? tipping_tags : []

  refs = repository.tag_names_contains(id, limit: limit) || []
  refs - excluded
end

#timestampObject



275
276
277
# File 'app/models/commit.rb', line 275

def timestamp
  committed_date.xmlschema
end

#tipping_branches(limit: 0) ⇒ Object



580
581
582
# File 'app/models/commit.rb', line 580

def tipping_branches(limit: 0)
  tipping_refs(Gitlab::Git::BRANCH_REF_PREFIX, limit: limit)
end

#tipping_tags(limit: 0) ⇒ Object



584
585
586
# File 'app/models/commit.rb', line 584

def tipping_tags(limit: 0)
  tipping_refs(Gitlab::Git::TAG_REF_PREFIX, limit: limit)
end

#titleObject

Returns the commits title.

Usually, the commit title is the first line of the commit message. In case this first line is longer than 100 characters, it is cut off after 80 characters + ‘…`



236
237
238
239
240
241
242
# File 'app/models/commit.rb', line 236

def title
  return full_title if full_title.length < 100

  # Use three dots instead of the ellipsis Unicode character because
  # some clients show the raw Unicode value in the merge commit.
  full_title.truncate(81, separator: ' ', omission: '...')
end

#to_ability_nameObject



524
525
526
# File 'app/models/commit.rb', line 524

def to_ability_name
  model_name.singular
end

#to_reference(from = nil, full: false) ⇒ Object



218
219
220
# File 'app/models/commit.rb', line 218

def to_reference(from = nil, full: false)
  commit_reference(from, id, full: full)
end

#touchObject



528
529
530
# File 'app/models/commit.rb', line 528

def touch
  # no-op but needs to be defined since #persisted? is defined
end

#touch_laterObject



532
533
534
535
536
# File 'app/models/commit.rb', line 532

def touch_later
  # No-op.
  # This method is called by ActiveRecord.
  # We don't want to do anything for `Commit` model, so this is empty.
end

#uri_type(path) ⇒ Object

Get the URI type of the given path

Used to build URLs to files in the repository in GFM.

path - String path to check

Examples:

uri_type('doc/README.md') # => :blob
uri_type('doc/logo.png')  # => :raw
uri_type('doc/api')       # => :tree
uri_type('not/found')     # => nil

Returns a symbol



496
497
498
499
500
501
502
503
504
505
506
# File 'app/models/commit.rb', line 496

def uri_type(path)
  entry = @raw.tree_entry(path)
  return unless entry

  if entry[:type] == :blob
    blob = ::Blob.decorate(Gitlab::Git::Blob.new(name: entry[:name]), container)
    blob.image? || blob.video? || blob.audio? ? :raw : :blob
  else
    entry[:type]
  end
end

#user_mention_classObject



568
569
570
# File 'app/models/commit.rb', line 568

def user_mention_class
  CommitUserMention
end

#user_mention_identifierObject



573
574
575
576
577
578
# File 'app/models/commit.rb', line 573

def user_mention_identifier
  {
    commit_id: id,
    note_id: nil
  }
end

#user_mentionsObject



336
337
338
# File 'app/models/commit.rb', line 336

def user_mentions
  user_mention_class.where(commit_id: self.id)
end

#with_pipelineObject



178
179
180
# File 'app/models/commit.rb', line 178

def with_pipeline
  @with_pipeline ||= Ci::CommitWithPipeline.new(self)
end