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, GlobalID::Identification, Mentionable, Noteable, Participable, Presentable, Referable, Repositories::StreamableDiff, 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
WHOLE_WORD_COMMIT_SHA_PATTERN =
/\b#{COMMIT_SHA_PATTERN}\b/
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
CO_AUTHORED_TRAILER =
"Co-authored-by"
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 Repositories::StreamableDiff

#diffs_for_streaming

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, #mentionable_attributes_changed?, #mentioned_filtered_user_ids_for, #parent_user, #refresh_markdown_cache, #refresh_markdown_cache!, #rendered_field_content, #skip_project_check?, #store_mentions!, #store_mentions?, #store_mentions_after_commit?, #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_projects, #referenced_users

Methods included from Participable

#participant?, #participants, #visible_participants

Methods included from Noteable

#after_note_created, #after_note_destroyed, #base_class_name, #broadcast_notes_changed, #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.



164
165
166
167
168
169
# File 'app/models/commit.rb', line 164

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



350
351
352
# File 'app/models/commit.rb', line 350

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.



28
29
30
# File 'app/models/commit.rb', line 28

def container
  @container
end

#rawObject

Returns the value of attribute raw.



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

def raw
  @raw
end

#redacted_description_htmlObject

Returns the value of attribute redacted_description_html.



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

def redacted_description_html
  @redacted_description_html
end

#redacted_full_title_htmlObject

Returns the value of attribute redacted_full_title_html.



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

def redacted_full_title_html
  @redacted_full_title_html
end

#redacted_title_htmlObject

Returns the value of attribute redacted_title_html.



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

def redacted_title_html
  @redacted_title_html
end

Class Method Details

.build_from_sidekiq_hash(project, hash) ⇒ Object



143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'app/models/commit.rb', line 143

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|
    hash[key] = Time.zone.parse(value) if key.to_s.end_with?(date_suffix) && value.is_a?(String)
  end

  from_hash(hash, project)
end

.decorate(commits, container) ⇒ Object



58
59
60
61
62
63
64
65
66
# File 'app/models/commit.rb', line 58

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



69
70
71
# File 'app/models/commit.rb', line 69

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

.diff_max_filesObject



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

def diff_max_files
  Gitlab::CurrentSettings.diff_max_files
end

.diff_max_linesObject



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

def diff_max_lines
  Gitlab::CurrentSettings.diff_max_lines
end

.diff_safe_max_filesObject



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

def diff_safe_max_files
  diff_max_files / DIFF_SAFE_LIMIT_FACTOR
end

.diff_safe_max_linesObject



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

def diff_safe_max_lines
  diff_max_lines / DIFF_SAFE_LIMIT_FACTOR
end

.from_hash(hash, container) ⇒ Object



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

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

.lazy(container, oid) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'app/models/commit.rb', line 125

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


215
216
217
218
219
# File 'app/models/commit.rb', line 215

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



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

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

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



73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'app/models/commit.rb', line 73

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



139
140
141
# File 'app/models/commit.rb', line 139

def parent_class
  ::Project
end

.reference_patternObject

Pattern used to extract commit references from text

This pattern supports cross-project references.



208
209
210
211
212
213
# File 'app/models/commit.rb', line 208

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

.reference_prefixObject



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

def self.reference_prefix
  '@'
end

.reference_valid?(reference) ⇒ Boolean

Returns:

  • (Boolean)


201
202
203
# File 'app/models/commit.rb', line 201

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

.truncate_sha(sha) ⇒ Object

Truncate sha to 8 characters



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

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

.underscoreObject



157
158
159
# File 'app/models/commit.rb', line 157

def underscore
  'commit'
end

.valid_hash?(key) ⇒ Boolean

Returns:

  • (Boolean)


121
122
123
# File 'app/models/commit.rb', line 121

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

Instance Method Details

#==(other) ⇒ Object



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

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

#authorObject



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

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

#author_full_textObject



257
258
259
260
261
262
263
# File 'app/models/commit.rb', line 257

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



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

def branches_containing(limit: 0, exclude_tipped: false)
  excluded = exclude_tipped ? tipping_branches : []

  repository.branch_names_contains(id, limit: limit, exclude_refs: excluded) || []
end

#cache_keyObject



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

def cache_key
  "commit:#{sha}"
end

#change_type_title(user) ⇒ Object



474
475
476
# File 'app/models/commit.rb', line 474

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

#cherry_pick_branch_nameObject



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

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

#cherry_pick_description(user) ⇒ Object



412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
# File 'app/models/commit.rb', line 412

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(load_from_gitaly: true)

    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



430
431
432
# File 'app/models/commit.rb', line 430

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

#committer(confirmed: true) ⇒ Object



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

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



267
268
269
270
271
272
# File 'app/models/commit.rb', line 267

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)


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

def description?
  description.present?
end

#diff_line_countObject



229
230
231
232
# File 'app/models/commit.rb', line 229

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

#diff_refsObject



362
363
364
365
366
367
# File 'app/models/commit.rb', line 362

def diff_refs
  Gitlab::Diff::DiffRefs.new(
    base_sha: self.parent_id || container.repository.blank_ref,
    head_sha: self.sha
  )
end

#diffs(diff_options = {}) ⇒ Object



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

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

#discussion_notesObject



342
343
344
# File 'app/models/commit.rb', line 342

def discussion_notes
  notes.non_diff_notes
end

#draft?Boolean Also known as: work_in_progress?

Returns:

  • (Boolean)


540
541
542
# File 'app/models/commit.rb', line 540

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

#first_diffs_slice(limit, diff_options = {}) ⇒ Object



598
599
600
# File 'app/models/commit.rb', line 598

def first_diffs_slice(limit, diff_options = {})
  diffs(diff_options.merge(max_files: limit)).diff_files
end

#full_titleObject

Returns the full commits title



248
249
250
251
252
253
254
255
# File 'app/models/commit.rb', line 248

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

#gpg_commitObject



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

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

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

Returns:

  • (Boolean)


463
464
465
466
467
468
469
470
471
472
# File 'app/models/commit.rb', line 463

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_encoded_file_paths?Boolean

Returns:

  • (Boolean)


590
591
592
# File 'app/models/commit.rb', line 590

def has_encoded_file_paths?
  raw_diffs.any?(&:encoded_file_path)
end

#has_signature?Boolean

Returns:

  • (Boolean)


369
370
371
# File 'app/models/commit.rb', line 369

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

#hook_attrs(with_changed_files: false) ⇒ Object



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

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
    }
  }

  data.merge!(repo_changes) if with_changed_files

  data
end

#idObject



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

def id
  raw.id
end

#lazy_authorObject



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

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)


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

def merge_commit?
  parent_ids.size > 1
end

#merged_merge_request(current_user) ⇒ Object



454
455
456
457
458
459
460
461
# File 'app/models/commit.rb', line 454

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)


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

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

#notesObject



334
335
336
# File 'app/models/commit.rb', line 334

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

#notes_with_associationsObject



346
347
348
# File 'app/models/commit.rb', line 346

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

#parentObject



328
329
330
331
332
# File 'app/models/commit.rb', line 328

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

#parentsObject



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

def parents
  # Usage of `reject` is intentional. `compact` doesn't work here, because of BatchLoader specifics
  @parents ||= parent_ids.map { |oid| Commit.lazy(container, oid) }.reject(&:nil?)
end

#persisted?Boolean

Returns:

  • (Boolean)


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

def persisted?
  true
end

#project_idObject



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

def project_id
  project&.id
end

#raw_deltasObject



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

def raw_deltas
  @deltas ||= raw.deltas
end

#raw_diffsObject



504
505
506
# File 'app/models/commit.rb', line 504

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

#raw_signature_typeObject



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

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

    if defined? @raw.raw_commit.signature_type
      @raw.raw_commit.signature_type
    end
  end
end

#readable_by?(user) ⇒ Boolean

Returns:

  • (Boolean)


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

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


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

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)


354
355
356
# File 'app/models/commit.rb', line 354

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

#revert_branch_nameObject



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

def revert_branch_name
  "revert-#{short_id}"
end

#revert_description(user) ⇒ Object



434
435
436
437
438
439
440
# File 'app/models/commit.rb', line 434

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



442
443
444
# File 'app/models/commit.rb', line 442

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

#reverts_commit?(commit, user) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#short_idObject



358
359
360
# File 'app/models/commit.rb', line 358

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



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

def tags_containing(limit: 0, exclude_tipped: false)
  excluded = exclude_tipped ? tipping_tags : []

  repository.tag_names_contains(id, limit: limit, exclude_refs: excluded) || []
end

#timestampObject



278
279
280
# File 'app/models/commit.rb', line 278

def timestamp
  committed_date.xmlschema
end

#tipping_branches(limit: 0) ⇒ Object



570
571
572
# File 'app/models/commit.rb', line 570

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

#tipping_tags(limit: 0) ⇒ Object



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

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 + ...



239
240
241
242
243
244
245
# File 'app/models/commit.rb', line 239

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



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

def to_ability_name
  model_name.singular
end

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



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

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

#touchObject



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

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

#touch_laterObject



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

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



492
493
494
495
496
497
498
499
500
501
502
# File 'app/models/commit.rb', line 492

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



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

def user_mention_class
  CommitUserMention
end

#user_mention_identifierObject



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

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

#user_mentionsObject



338
339
340
# File 'app/models/commit.rb', line 338

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

#valid_full_shaObject



594
595
596
# File 'app/models/commit.rb', line 594

def valid_full_sha
  id.match(Gitlab::Git::Commit::FULL_SHA_PATTERN).to_s
end

#with_pipelineObject



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

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