Class: Bringit::Commit

Inherits:
Object
  • Object
show all
Includes:
EncodingHelper
Defined in:
lib/bringit/commit.rb

Constant Summary collapse

SERIALIZE_KEYS =
[
  :id, :message, :parent_ids,
  :authored_date, :author_name, :author_email,
  :committed_date, :committer_name, :committer_email
].freeze

Constants included from EncodingHelper

EncodingHelper::ENCODING_CONFIDENCE_THRESHOLD

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from EncodingHelper

#encode!, #encode_utf8

Constructor Details

#initialize(raw_commit, repository = nil, head = nil) ⇒ Commit

Returns a new instance of Commit.



141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/bringit/commit.rb', line 141

def initialize(raw_commit, repository = nil, head = nil)
  raise "Nil as raw commit passed" unless raw_commit

  if raw_commit.is_a?(Hash)
    init_from_hash(raw_commit)
  elsif raw_commit.is_a?(Rugged::Commit)
    init_from_rugged(raw_commit)
  else
    raise "Invalid raw commit type: #{raw_commit.class}"
  end

  @repository = repository
  @head = head
end

Instance Attribute Details

#headObject

Returns the value of attribute head.



7
8
9
# File 'lib/bringit/commit.rb', line 7

def head
  @head
end

#raw_commitObject

Returns the value of attribute raw_commit.



7
8
9
# File 'lib/bringit/commit.rb', line 7

def raw_commit
  @raw_commit
end

#refsObject

Get a collection of Rugged::Reference objects for this commit.

Ex.

commit.ref


243
244
245
# File 'lib/bringit/commit.rb', line 243

def refs
  @refs
end

#repositoryObject (readonly)

Returns the value of attribute repository.



6
7
8
# File 'lib/bringit/commit.rb', line 6

def repository
  @repository
end

Class Method Details

.between(repo, base, head) ⇒ Object

Get commits between two revspecs See also #repository.commits_between

Ex.

Commit.between(repo, '29eda46b', 'master')


104
105
106
107
108
109
110
# File 'lib/bringit/commit.rb', line 104

def between(repo, base, head)
  repo.commits_between(base, head).map do |commit|
    decorate(commit, repo)
  end
rescue Rugged::ReferenceError
  []
end

.decorate(commit, repository, ref = nil) ⇒ Object



117
118
119
# File 'lib/bringit/commit.rb', line 117

def decorate(commit, repository, ref = nil)
  Bringit::Commit.new(commit, repository, ref)
end

.diff_from_parent(rugged_commit, options = {}) ⇒ Object

Returns a diff object for the changes introduced by rugged_commit. If rugged_commit doesn’t have a parent, then the diff is between this commit and an empty repo. See Repository#diff for the keys allowed in the options hash.



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

def diff_from_parent(rugged_commit, options = {})
  options ||= {}
  break_rewrites = options[:break_rewrites]
  actual_options = Bringit::Diff.filter_diff_options(options)

  diff = if rugged_commit.parents.empty?
            rugged_commit.diff(actual_options.merge(reverse: true))
          else
            rugged_commit.parents[0].diff(rugged_commit, actual_options)
          end

  diff.find_similar!(break_rewrites: break_rewrites)
  diff
end

.find(repo, commit_id = "HEAD") ⇒ Object

Get single commit

Ex.

Commit.find(repo, '29eda46b')

Commit.find(repo, 'master')


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/bringit/commit.rb', line 57

def find(repo, commit_id = "HEAD")
  return decorate(commit_id, repo) if commit_id.is_a?(Rugged::Commit)

  obj = if commit_id.is_a?(String)
          repo.rev_parse_target(commit_id)
        else
          Bringit::Ref.dereference_object(commit_id)
        end

  return nil unless obj.is_a?(Rugged::Commit)

  decorate(obj, repo)
rescue Rugged::ReferenceError, Rugged::InvalidError, Rugged::ObjectError, Bringit::Repository::NoRepository
  nil
end

.find_all(repo, options = {}) ⇒ Object

Delegate Repository#find_commits



113
114
115
# File 'lib/bringit/commit.rb', line 113

def find_all(repo, options = {})
  repo.find_commits(options)
end

.last(repo) ⇒ Object

Get last commit for HEAD

Ex.

Commit.last(repo)


78
79
80
# File 'lib/bringit/commit.rb', line 78

def last(repo)
  find(repo)
end

.last_for_path(repo, ref, path = nil) ⇒ Object

Get last commit for specified path and ref

Ex.

Commit.last_for_path(repo, '29eda46b', 'app/models')

Commit.last_for_path(repo, 'master', 'Gemfile')


89
90
91
92
93
94
95
96
# File 'lib/bringit/commit.rb', line 89

def last_for_path(repo, ref, path = nil)
  where(
    repo: repo,
    ref: ref,
    path: path,
    limit: 1
  ).first
end

.where(options) ⇒ Object

Get commits collection

Ex.

Commit.where(
  repo: repo,
  ref: 'master',
  path: 'app/models',
  limit: 10,
  offset: 5,
)


43
44
45
46
47
48
# File 'lib/bringit/commit.rb', line 43

def where(options)
  repo = options.delete(:repo)
  raise 'Bringit::Repository is required' unless repo.respond_to?(:log)

  repo.log(options).map { |c| decorate(c, repo) }
end

Instance Method Details

#==(other) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
# File 'lib/bringit/commit.rb', line 19

def ==(other)
  return false unless other.is_a?(Bringit::Commit)

  methods = [:message, :parent_ids, :authored_date, :author_name,
              :author_email, :committed_date, :committer_name,
              :committer_email]

  methods.all? do |method|
    send(method) == other.send(method)
  end
end

#author_emailObject



289
290
291
# File 'lib/bringit/commit.rb', line 289

def author_email
  encode! @author_email
end

#author_nameObject



285
286
287
# File 'lib/bringit/commit.rb', line 285

def author_name
  encode! @author_name
end

#committer_emailObject



297
298
299
# File 'lib/bringit/commit.rb', line 297

def committer_email
  encode! @committer_email
end

#committer_nameObject



293
294
295
# File 'lib/bringit/commit.rb', line 293

def committer_name
  encode! @committer_name
end

#created_atObject



168
169
170
# File 'lib/bringit/commit.rb', line 168

def created_at
  committed_date
end

#dateObject



212
213
214
# File 'lib/bringit/commit.rb', line 212

def date
  committed_date
end

#diff_from_parent(options = {}) ⇒ Object

Returns a diff object for the changes from this commit’s first parent. If there is no parent, then the diff is between this commit and an empty repo. See Repository#diff for keys allowed in the options hash.



192
193
194
# File 'lib/bringit/commit.rb', line 192

def diff_from_parent(options = {})
  Commit.diff_from_parent(raw_commit, options)
end

#different_committer?Boolean

Was this commit committed by a different person than the original author?

Returns:

  • (Boolean)


173
174
175
# File 'lib/bringit/commit.rb', line 173

def different_committer?
  author_name != committer_name || author_email != committer_email
end

#diffs(options = {}) ⇒ Object



216
217
218
# File 'lib/bringit/commit.rb', line 216

def diffs(options = {})
  Bringit::DiffCollection.new(diff_from_parent(options), options)
end

#has_zero_stats?Boolean

Returns:

  • (Boolean)


196
197
198
199
200
# File 'lib/bringit/commit.rb', line 196

def has_zero_stats?
  stats.total.zero?
rescue
  true
end

#messageObject



281
282
283
# File 'lib/bringit/commit.rb', line 281

def message
  encode! @message
end

#no_commit_messageObject



202
203
204
# File 'lib/bringit/commit.rb', line 202

def no_commit_message
  "--no commit message"
end

#parent_idObject



177
178
179
# File 'lib/bringit/commit.rb', line 177

def parent_id
  parent_ids.first
end

#parentsObject



220
221
222
# File 'lib/bringit/commit.rb', line 220

def parents
  raw_commit.parents.map { |c| Bringit::Commit.new(c, repository) }
end

#ref_namesObject

Get ref names collection

Ex.

commit.ref_names


275
276
277
278
279
# File 'lib/bringit/commit.rb', line 275

def ref_names
  repository.refs_hash[id].map do |ref|
    ref.name.sub(%r{^refs/(heads|remotes|tags)/}, "")
  end
end

#referencesObject

Get a collection of Bringit::Ref (its subclasses) objects



248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/bringit/commit.rb', line 248

def references
  refs.map do |ref|
    if ref.name.match(%r{\Arefs/heads/})
      Bringit::Branch.new(repository, ref.name, ref.target)
    elsif ref.name.match(%r{\Arefs/tags/})
      message = nil

      if ref.target.is_a?(Rugged::Tag::Annotation)
        tag_message = ref.target.message

        if tag_message.respond_to?(:chomp)
          message = tag_message.chomp
        end
      end

      Bringit::Tag.new(self, ref.name, ref.target, message)
    else
      Bringit::Ref.new(repository, ref.name, ref.target)
    end
  end
end

#safe_messageObject



164
165
166
# File 'lib/bringit/commit.rb', line 164

def safe_message
  @safe_message ||= message
end

#shaObject



156
157
158
# File 'lib/bringit/commit.rb', line 156

def sha
  id
end

#short_id(length = 10) ⇒ Object



160
161
162
# File 'lib/bringit/commit.rb', line 160

def short_id(length = 10)
  id.to_s[0..length]
end

#statsObject



224
225
226
# File 'lib/bringit/commit.rb', line 224

def stats
  Bringit::CommitStats.new(self)
end

#to_diff(options = {}) ⇒ Object

Shows the diff between the commit’s parent and the commit.

Cuts out the header and stats from #to_patch and returns only the diff.



184
185
186
# File 'lib/bringit/commit.rb', line 184

def to_diff(options = {})
  diff_from_parent(options).patch
end

#to_hashObject



206
207
208
209
210
# File 'lib/bringit/commit.rb', line 206

def to_hash
  serialize_keys.map.with_object({}) do |key, hash|
    hash[key] = send(key)
  end
end

#to_patch(options = {}) ⇒ Object



228
229
230
231
232
233
234
235
236
# File 'lib/bringit/commit.rb', line 228

def to_patch(options = {})
  begin
    raw_commit.to_mbox(options)
  rescue Rugged::InvalidError => ex
    if ex.message =~ /Commit \w+ is a merge commit/
      'Patch format is not currently supported for merge commits.'
    end
  end
end