Class: Grit::Commit

Inherits:
Object
  • Object
show all
Defined in:
lib/grit/lib/grit/commit.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(repo, id, parents, tree, author, authored_date, committer, committed_date, message) ⇒ Commit

Instantiate a new Commit

+id+ is the id of the commit
+parents+ is an array of commit ids (will be converted into Commit instances)
+tree+ is the correspdonding tree id (will be converted into a Tree object)
+author+ is the author string
+authored_date+ is the authored Time
+committer+ is the committer string
+committed_date+ is the committed Time
+message+ is an array of commit message lines

Returns Grit::Commit (baked)



26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/grit/lib/grit/commit.rb', line 26

def initialize(repo, id, parents, tree, author, authored_date, committer, committed_date, message)
  @repo = repo
  @id = id
  @parents = parents.map { |p| Commit.create(repo, :id => p) }
  @tree = Tree.create(repo, :id => tree)
  @author = author
  @authored_date = authored_date
  @committer = committer
  @committed_date = committed_date
  @message = message.join("\n")
  @short_message = message.select { |x| !x.strip.empty? }[0] || ''
end

Instance Attribute Details

#idObject (readonly)

Returns the value of attribute id.



4
5
6
# File 'lib/grit/lib/grit/commit.rb', line 4

def id
  @id
end

Class Method Details

.actor(line) ⇒ Object

Parse out the actor (author or committer) info

Returns [String (actor name and email), Time (acted at time)]



218
219
220
221
# File 'lib/grit/lib/grit/commit.rb', line 218

def self.actor(line)
  m, actor, epoch = *line.match(/^.+? (.*) (\d+) .*$/)
  [Actor.from_string(actor), Time.at(epoch.to_i)]
end

.count(repo, ref) ⇒ Object

Count the number of commits reachable from this ref

+repo+ is the Repo
+ref+ is the ref from which to begin (SHA1 or name)

Returns Integer



74
75
76
# File 'lib/grit/lib/grit/commit.rb', line 74

def self.count(repo, ref)
  repo.git.rev_list({}, ref).size / 41
end

.create(repo, atts) ⇒ Object

Create an unbaked Commit containing just the specified attributes

+repo+ is the Repo
+atts+ is a Hash of instance variable data

Returns Grit::Commit (unbaked)



48
49
50
# File 'lib/grit/lib/grit/commit.rb', line 48

def self.create(repo, atts)
  self.allocate.create_initialize(repo, atts)
end

.diff(repo, a, b = nil, paths = []) ⇒ Object

Show diffs between two trees:

+repo+ is the Repo
+a+ is a named commit
+b+ is an optional named commit.  Passing an array assumes you
  wish to omit the second named commit and limit the diff to the
  given paths.
+paths* is an array of paths to limit the diff.

Returns Grit::Diff[] (baked)



152
153
154
155
156
157
158
159
160
161
162
# File 'lib/grit/lib/grit/commit.rb', line 152

def self.diff(repo, a, b = nil, paths = [])
  if b.is_a?(Array)
    paths = b
    b     = nil
  end
  paths.unshift("--") unless paths.empty?
  paths.unshift(b)    unless b.nil?
  paths.unshift(a)
  text = repo.git.diff({:full_index => true}, *paths)
  Diff.list_from_string(repo, text)
end

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

Find all commits matching the given criteria.

+repo+ is the Repo
+ref+ is the ref from which to begin (SHA1 or name) or nil for --all
+options+ is a Hash of optional arguments to git
  :max_count is the maximum number of commits to fetch
  :skip is the number of commits to skip

Returns Grit::Commit[] (baked)



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/grit/lib/grit/commit.rb', line 86

def self.find_all(repo, ref, options = {})
  allowed_options = [:max_count, :skip, :since]

  default_options = {:pretty => "raw"}
  actual_options = default_options.merge(options)

  if ref
    output = repo.git.rev_list(actual_options, ref)
  else
    output = repo.git.rev_list(actual_options.merge(:all => true))
  end

  self.list_from_string(repo, output)
rescue Grit::GitRuby::Repository::NoSuchShaFound
  []
end

.list_from_string(repo, text) ⇒ Object

Parse out commit information into an array of baked Commit objects

+repo+ is the Repo
+text+ is the text output from the git command (raw format)

Returns Grit::Commit[] (baked)

really should re-write this to be more accepting of non-standard commit messages

  • it broke when ‘encoding’ was introduced - not sure what else might show up



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/grit/lib/grit/commit.rb', line 112

def self.list_from_string(repo, text)
  lines = text.split("\n")

  commits = []

  while !lines.empty?
    id = lines.shift.split.last
    tree = lines.shift.split.last

    parents = []
    parents << lines.shift.split.last while lines.first =~ /^parent/

    author, authored_date = self.actor(lines.shift)
    committer, committed_date = self.actor(lines.shift)

    # not doing anything with this yet, but it's sometimes there
    encoding = lines.shift.split.last if lines.first =~ /^encoding/

    lines.shift

    message_lines = []
    message_lines << lines.shift[4..-1] while lines.first =~ /^ {4}/

    lines.shift while lines.first && lines.first.empty?

    commits << Commit.new(repo, id, parents, tree, author, authored_date, committer, committed_date, message_lines)
  end

  commits
end

Instance Method Details

#author_stringObject



223
224
225
# File 'lib/grit/lib/grit/commit.rb', line 223

def author_string
  "%s <%s> %s %+05d" % [author.name, author.email, authored_date.to_i, 800]
end

#create_initialize(repo, atts) ⇒ Object

Initializer for Commit.create

+repo+ is the Repo
+atts+ is a Hash of instance variable data

Returns Grit::Commit (unbaked)



57
58
59
60
61
62
63
# File 'lib/grit/lib/grit/commit.rb', line 57

def create_initialize(repo, atts)
  @repo = repo
  atts.each do |k, v|
    instance_variable_set("@#{k}", v)
  end
  self
end

#dateObject



200
201
202
# File 'lib/grit/lib/grit/commit.rb', line 200

def date
  @committed_date
end

#diffsObject



179
180
181
182
183
184
185
# File 'lib/grit/lib/grit/commit.rb', line 179

def diffs
  if parents.empty?
    show
  else
    self.class.diff(@repo, parents.first.id, @id)
  end
end

#id_abbrevObject



39
40
41
# File 'lib/grit/lib/grit/commit.rb', line 39

def id_abbrev
  @id_abbrev ||= @repo.git.rev_parse({}, self.id).chomp[0, 7]
end

#inspectObject

Pretty object inspection



209
210
211
# File 'lib/grit/lib/grit/commit.rb', line 209

def inspect
  %Q{#<Grit::Commit "#{@id}">}
end

#lazy_sourceObject



65
66
67
# File 'lib/grit/lib/grit/commit.rb', line 65

def lazy_source
  self.class.find_all(@repo, @id, {:max_count => 1}).first
end

#shaObject



196
197
198
# File 'lib/grit/lib/grit/commit.rb', line 196

def sha
  @id
end

#showObject



164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/grit/lib/grit/commit.rb', line 164

def show
  if parents.size > 1
    diff = @repo.git.native("diff #{parents[0].id}...#{parents[1].id}", {:full_index => true})
  else
    diff = @repo.git.show({:full_index => true, :pretty => 'raw'}, @id)
  end

  if diff =~ /diff --git a/
    diff = diff.sub(/.+?(diff --git a)/m, '\1')
  else
    diff = ''
  end
  Diff.list_from_string(@repo, diff)
end

#statsObject



187
188
189
# File 'lib/grit/lib/grit/commit.rb', line 187

def stats
  stats = @repo.commit_stats(self.sha, 1)[0][-1]
end

#to_hashObject



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/grit/lib/grit/commit.rb', line 227

def to_hash
  {
    'id'       => id,
    'parents'  => parents.map { |p| { 'id' => p.id } },
    'tree'     => tree.id,
    'message'  => message,
    'author'   => {
      'name'  => author.name,
      'email' => author.email
    },
    'committer' => {
      'name'  => committer.name,
      'email' => committer.email
    },
    'authored_date'  => authored_date.xmlschema,
    'committed_date' => committed_date.xmlschema,
  }
end

#to_patchObject



204
205
206
# File 'lib/grit/lib/grit/commit.rb', line 204

def to_patch
  @repo.git.format_patch({'1' => true, :stdout => true}, to_s)
end

#to_sObject

Convert this Commit to a String which is just the SHA1 id



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

def to_s
  @id
end