grit 0.7.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grit might be problematic. Click here for more details.

data/lib/grit/tree.rb ADDED
@@ -0,0 +1,109 @@
1
+ module Grit
2
+
3
+ class Tree
4
+ include Lazy
5
+
6
+ lazy_reader :contents
7
+ attr_reader :id
8
+ attr_reader :mode
9
+ attr_reader :name
10
+
11
+ def initialize
12
+ @contents = nil
13
+ @__baked__ = nil
14
+ end
15
+
16
+ # Construct the contents of the tree
17
+ # +repo+ is the Repo
18
+ # +treeish+ is the reference
19
+ # +paths+ is an optional Array of directory paths to restrict the tree
20
+ #
21
+ # Returns Grit::Tree (baked)
22
+ def self.construct(repo, treeish, paths = [])
23
+ output = repo.git.ls_tree({}, treeish, paths.join(" "))
24
+
25
+ self.allocate.construct_initialize(repo, treeish, output)
26
+ end
27
+
28
+ def construct_initialize(repo, id, text)
29
+ @repo = repo
30
+ @id = id
31
+ @contents = []
32
+ @__baked__ = nil
33
+
34
+ text.split("\n").each do |line|
35
+ @contents << content_from_string(repo, line)
36
+ end
37
+ __baked__
38
+ self
39
+ end
40
+
41
+ def __bake__
42
+ temp = Tree.construct(@repo, @id, [])
43
+ @contents = temp.contents
44
+ end
45
+
46
+ # Create an unbaked Tree containing just the specified attributes
47
+ # +repo+ is the Repo
48
+ # +atts+ is a Hash of instance variable data
49
+ #
50
+ # Returns Grit::Tree (unbaked)
51
+ def self.create(repo, atts)
52
+ self.allocate.create_initialize(repo, atts)
53
+ end
54
+
55
+ # Initializer for Tree.create
56
+ # +repo+ is the Repo
57
+ # +atts+ is a Hash of instance variable data
58
+ #
59
+ # Returns Grit::Tree (unbaked)
60
+ def create_initialize(repo, atts)
61
+ @repo = repo
62
+ @contents = nil
63
+ @__baked__ = nil
64
+
65
+ atts.each do |k, v|
66
+ instance_variable_set("@#{k}".to_sym, v)
67
+ end
68
+ self
69
+ end
70
+
71
+ # Parse a content item and create the appropriate object
72
+ # +repo+ is the Repo
73
+ # +text+ is the single line containing the items data in `git ls-tree` format
74
+ #
75
+ # Returns Grit::Blob or Grit::Tree
76
+ def content_from_string(repo, text)
77
+ mode, type, id, name = text.split(" ", 4)
78
+ case type
79
+ when "tree"
80
+ Tree.create(repo, :id => id, :mode => mode, :name => name)
81
+ when "blob"
82
+ Blob.create(repo, :id => id, :mode => mode, :name => name)
83
+ when "commit"
84
+ nil
85
+ else
86
+ raise "Invalid type: #{type}"
87
+ end
88
+ end
89
+
90
+ # Find the named object in this tree's contents
91
+ #
92
+ # Examples
93
+ # Repo.new('/path/to/grit').tree/'lib'
94
+ # # => #<Grit::Tree "6cc23ee138be09ff8c28b07162720018b244e95e">
95
+ # Repo.new('/path/to/grit').tree/'README.txt'
96
+ # # => #<Grit::Blob "8b1e02c0fb554eed2ce2ef737a68bb369d7527df">
97
+ #
98
+ # Returns Grit::Blob or Grit::Tree or nil if not found
99
+ def /(file)
100
+ self.contents.select { |c| c.name == file }.first
101
+ end
102
+
103
+ # Pretty object inspection
104
+ def inspect
105
+ %Q{#<Grit::Tree "#{@id}">}
106
+ end
107
+ end # Tree
108
+
109
+ end # Grit
@@ -0,0 +1,131 @@
1
+ 634396b2f541a9f2d58b00be1a07f0c358b999b3 1 1 7
2
+ author Tom Preston-Werner
3
+ author-mail <tom@mojombo.com>
4
+ author-time 1191997100
5
+ author-tz -0700
6
+ committer Tom Preston-Werner
7
+ committer-mail <tom@mojombo.com>
8
+ committer-time 1191997100
9
+ committer-tz -0700
10
+ filename lib/grit.rb
11
+ summary initial grit setup
12
+ boundary
13
+ $:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
14
+ 634396b2f541a9f2d58b00be1a07f0c358b999b3 2 2
15
+
16
+ 634396b2f541a9f2d58b00be1a07f0c358b999b3 3 3
17
+ # core
18
+ 634396b2f541a9f2d58b00be1a07f0c358b999b3 4 4
19
+
20
+ 634396b2f541a9f2d58b00be1a07f0c358b999b3 5 5
21
+ # stdlib
22
+ 634396b2f541a9f2d58b00be1a07f0c358b999b3 6 6
23
+
24
+ 634396b2f541a9f2d58b00be1a07f0c358b999b3 7 7
25
+ # internal requires
26
+ 3b1930208a82457747d76729ae088e90edca4673 8 8 1
27
+ author Tom Preston-Werner
28
+ author-mail <tom@mojombo.com>
29
+ author-time 1192267241
30
+ author-tz -0700
31
+ committer Tom Preston-Werner
32
+ committer-mail <tom@mojombo.com>
33
+ committer-time 1192267241
34
+ committer-tz -0700
35
+ filename lib/grit.rb
36
+ summary big refactor to do lazy loading
37
+ require 'grit/lazy'
38
+ 4c8124ffcf4039d292442eeccabdeca5af5c5017 8 9 1
39
+ author Tom Preston-Werner
40
+ author-mail <tom@mojombo.com>
41
+ author-time 1191999972
42
+ author-tz -0700
43
+ committer Tom Preston-Werner
44
+ committer-mail <tom@mojombo.com>
45
+ committer-time 1191999972
46
+ committer-tz -0700
47
+ filename lib/grit.rb
48
+ summary implement Grit#heads
49
+ require 'grit/errors'
50
+ d01a4cfad6ea50285c4710243e3cbe019d381eba 9 10 1
51
+ author Tom Preston-Werner
52
+ author-mail <tom@mojombo.com>
53
+ author-time 1192032303
54
+ author-tz -0700
55
+ committer Tom Preston-Werner
56
+ committer-mail <tom@mojombo.com>
57
+ committer-time 1192032303
58
+ committer-tz -0700
59
+ filename lib/grit.rb
60
+ summary convert to Grit module, refactor to be more OO
61
+ require 'grit/git'
62
+ 4c8124ffcf4039d292442eeccabdeca5af5c5017 9 11 1
63
+ require 'grit/head'
64
+ a47fd41f3aa4610ea527dcc1669dfdb9c15c5425 10 12 1
65
+ author Tom Preston-Werner
66
+ author-mail <tom@mojombo.com>
67
+ author-time 1192002639
68
+ author-tz -0700
69
+ committer Tom Preston-Werner
70
+ committer-mail <tom@mojombo.com>
71
+ committer-time 1192002639
72
+ committer-tz -0700
73
+ filename lib/grit.rb
74
+ summary add more comments throughout
75
+ require 'grit/commit'
76
+ b17b974691f0a26f26908495d24d9c4c718920f8 13 13 1
77
+ author Tom Preston-Werner
78
+ author-mail <tom@mojombo.com>
79
+ author-time 1192271832
80
+ author-tz -0700
81
+ committer Tom Preston-Werner
82
+ committer-mail <tom@mojombo.com>
83
+ committer-time 1192271832
84
+ committer-tz -0700
85
+ filename lib/grit.rb
86
+ summary started implementing Tree
87
+ require 'grit/tree'
88
+ 74fd66519e983a0f29e16a342a6059dbffe36020 14 14 1
89
+ author Tom Preston-Werner
90
+ author-mail <tom@mojombo.com>
91
+ author-time 1192317005
92
+ author-tz -0700
93
+ committer Tom Preston-Werner
94
+ committer-mail <tom@mojombo.com>
95
+ committer-time 1192317005
96
+ committer-tz -0700
97
+ filename lib/grit.rb
98
+ summary add Blob
99
+ require 'grit/blob'
100
+ d01a4cfad6ea50285c4710243e3cbe019d381eba 12 15 1
101
+ require 'grit/repo'
102
+ 634396b2f541a9f2d58b00be1a07f0c358b999b3 9 16 1
103
+
104
+ d01a4cfad6ea50285c4710243e3cbe019d381eba 14 17 1
105
+ module Grit
106
+ b6e1b765e0c15586a2c5b9832854f95defd71e1f 18 18 6
107
+ author Tom Preston-Werner
108
+ author-mail <tom@mojombo.com>
109
+ author-time 1192860483
110
+ author-tz -0700
111
+ committer Tom Preston-Werner
112
+ committer-mail <tom@mojombo.com>
113
+ committer-time 1192860483
114
+ committer-tz -0700
115
+ filename lib/grit.rb
116
+ summary implement Repo.init_bare
117
+ class << self
118
+ b6e1b765e0c15586a2c5b9832854f95defd71e1f 19 19
119
+ attr_accessor :debug
120
+ b6e1b765e0c15586a2c5b9832854f95defd71e1f 20 20
121
+ end
122
+ b6e1b765e0c15586a2c5b9832854f95defd71e1f 21 21
123
+
124
+ b6e1b765e0c15586a2c5b9832854f95defd71e1f 22 22
125
+ self.debug = false
126
+ b6e1b765e0c15586a2c5b9832854f95defd71e1f 23 23
127
+
128
+ 634396b2f541a9f2d58b00be1a07f0c358b999b3 11 24 2
129
+ VERSION = '1.0.0'
130
+ 634396b2f541a9f2d58b00be1a07f0c358b999b3 12 25
131
+ end
@@ -0,0 +1 @@
1
+ Hello world
@@ -0,0 +1 @@
1
+ 11
@@ -0,0 +1,610 @@
1
+ diff --git a/.gitignore b/.gitignore
2
+ index 4ebc8aea50e0a67e000ba29a30809d0a7b9b2666..2dd02534615434d88c51307beb0f0092f21fd103 100644
3
+ --- a/.gitignore
4
+ +++ b/.gitignore
5
+ @@ -1 +1,2 @@
6
+ coverage
7
+ +pkg
8
+ diff --git a/Manifest.txt b/Manifest.txt
9
+ index 641972d82c6d1b51122274ae8f6a0ecdfb56ee22..38bf80c54a526e76d74820a0f48606fe1ca7b1be 100644
10
+ --- a/Manifest.txt
11
+ +++ b/Manifest.txt
12
+ @@ -4,4 +4,31 @@ README.txt
13
+ Rakefile
14
+ bin/grit
15
+ lib/grit.rb
16
+ -test/test_grit.rb
17
+
18
+ +lib/grit/actor.rb
19
+ +lib/grit/blob.rb
20
+ +lib/grit/commit.rb
21
+ +lib/grit/errors.rb
22
+ +lib/grit/git.rb
23
+ +lib/grit/head.rb
24
+ +lib/grit/lazy.rb
25
+ +lib/grit/repo.rb
26
+ +lib/grit/tree.rb
27
+ +test/fixtures/blame
28
+ +test/fixtures/cat_file_blob
29
+ +test/fixtures/cat_file_blob_size
30
+ +test/fixtures/for_each_ref
31
+ +test/fixtures/ls_tree_a
32
+ +test/fixtures/ls_tree_b
33
+ +test/fixtures/rev_list
34
+ +test/fixtures/rev_list_single
35
+ +test/helper.rb
36
+ +test/profile.rb
37
+ +test/suite.rb
38
+ +test/test_actor.rb
39
+ +test/test_blob.rb
40
+ +test/test_commit.rb
41
+ +test/test_git.rb
42
+ +test/test_head.rb
43
+ +test/test_reality.rb
44
+ +test/test_repo.rb
45
+ +test/test_tree.rb
46
+ diff --git a/README.txt b/README.txt
47
+ index 8b1e02c0fb554eed2ce2ef737a68bb369d7527df..fca94f84afd7d749c62626011f972a509f6a5ac6 100644
48
+ --- a/README.txt
49
+ +++ b/README.txt
50
+ @@ -1,32 +1,185 @@
51
+ grit
52
+ - by FIX (your name)
53
+ - FIX (url)
54
+ + by Tom Preston-Werner
55
+ + grit.rubyforge.org
56
+
57
+ == DESCRIPTION:
58
+ +
59
+ +Grit is a Ruby library for extracting information from a git repository in and
60
+ +object oriented manner.
61
+ +
62
+ +== REQUIREMENTS:
63
+ +
64
+ +* git (http://git.or.cz) tested with 1.5.3.4
65
+ +
66
+ +== INSTALL:
67
+ +
68
+ +sudo gem install grit
69
+ +
70
+ +== USAGE:
71
+ +
72
+ +Grit gives you object model access to your git repository. Once you have
73
+ +created a repository object, you can traverse it to find parent commit(s),
74
+ +trees, blobs, etc.
75
+ +
76
+ += Initialize a Repo object
77
+ +
78
+ +The first step is to create a Grit::Repo object to represent your repo. I
79
+ +include the Grit module so reduce typing.
80
+ +
81
+ + include Grit
82
+ + repo = Repo.new("/Users/tom/dev/grit")
83
+
84
+ -FIX (describe your package)
85
+ +In the above example, the directory /Users/tom/dev/grit is my working
86
+ +repo and contains the .git directory. You can also initialize Grit with a
87
+ +bare repo.
88
+
89
+ -== FEATURES/PROBLEMS:
90
+ + repo = Repo.new("/var/git/grit.git")
91
+
92
+ -* FIX (list of features or problems)
93
+ += Getting a list of commits
94
+
95
+ -== SYNOPSIS:
96
+ +From the Repo object, you can get a list of commits as an array of Commit
97
+ +objects.
98
+
99
+ - FIX (code sample of usage)
100
+ + repo.commits
101
+ + # => [#<Grit::Commit "e80bbd2ce67651aa18e57fb0b43618ad4baf7750">,
102
+ + #<Grit::Commit "91169e1f5fa4de2eaea3f176461f5dc784796769">,
103
+ + #<Grit::Commit "038af8c329ef7c1bae4568b98bd5c58510465493">,
104
+ + #<Grit::Commit "40d3057d09a7a4d61059bca9dca5ae698de58cbe">,
105
+ + #<Grit::Commit "4ea50f4754937bf19461af58ce3b3d24c77311d9">]
106
+ +
107
+ +Called without arguments, Repo#commits returns a list of up to ten commits
108
+ +reachable by the master branch (starting at the latest commit). You can ask
109
+ +for commits beginning at a different branch, commit, tag, etc.
110
+
111
+ -== REQUIREMENTS:
112
+ + repo.commits('mybranch')
113
+ + repo.commits('40d3057d09a7a4d61059bca9dca5ae698de58cbe')
114
+ + repo.commits('v0.1')
115
+ +
116
+ +You can specify the maximum number of commits to return.
117
+
118
+ -* FIX (list of requirements)
119
+ + repo.commits('master', 100)
120
+ +
121
+ +If you need paging, you can specify a number of commits to skip.
122
+
123
+ -== INSTALL:
124
+ + repo.commits('master', 10, 20)
125
+ +
126
+ +The above will return commits 21-30 from the commit list.
127
+ +
128
+ += The Commit object
129
+ +
130
+ +Commit objects contain information about that commit.
131
+ +
132
+ + head = repo.commits.first
133
+ +
134
+ + head.id
135
+ + # => "e80bbd2ce67651aa18e57fb0b43618ad4baf7750"
136
+ +
137
+ + head.parents
138
+ + # => [#<Grit::Commit "91169e1f5fa4de2eaea3f176461f5dc784796769">]
139
+ +
140
+ + head.tree
141
+ + # => #<Grit::Tree "3536eb9abac69c3e4db583ad38f3d30f8db4771f">
142
+ +
143
+ + head.author
144
+ + # => #<Grit::Actor "Tom Preston-Werner <tom@mojombo.com>">
145
+ +
146
+ + head.authored_date
147
+ + # => Wed Oct 24 22:02:31 -0700 2007
148
+ +
149
+ + head.committer
150
+ + # => #<Grit::Actor "Tom Preston-Werner <tom@mojombo.com>">
151
+ +
152
+ + head.committed_date
153
+ + # => Wed Oct 24 22:02:31 -0700 2007
154
+ +
155
+ + head.message
156
+ + # => "add Actor inspect"
157
+ +
158
+ +You can traverse a commit's ancestry by chaining calls to #parents.
159
+ +
160
+ + repo.commits.first.parents[0].parents[0].parents[0]
161
+ +
162
+ +The above corresponds to master^^^ or master~3 in git parlance.
163
+ +
164
+ += The Tree object
165
+ +
166
+ +A tree records pointers to the contents of a directory. Let's say you want
167
+ +the root tree of the latest commit on the master branch.
168
+ +
169
+ + tree = repo.commits.first.tree
170
+ + # => #<Grit::Tree "3536eb9abac69c3e4db583ad38f3d30f8db4771f">
171
+ +
172
+ + tree.id
173
+ + # => "3536eb9abac69c3e4db583ad38f3d30f8db4771f"
174
+ +
175
+ +Once you have a tree, you can get the contents.
176
+ +
177
+ + contents = tree.contents
178
+ + # => [#<Grit::Blob "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666">,
179
+ + #<Grit::Blob "81d2c27608b352814cbe979a6acd678d30219678">,
180
+ + #<Grit::Tree "c3d07b0083f01a6e1ac969a0f32b8d06f20c62e5">,
181
+ + #<Grit::Tree "4d00fe177a8407dbbc64a24dbfc564762c0922d8">]
182
+ +
183
+ +This tree contains two Blob objects and two Tree objects. The trees are
184
+ +subdirectories and the blobs are files. Trees below the root have additional
185
+ +attributes.
186
+ +
187
+ + contents.last.name
188
+ + # => "lib"
189
+ +
190
+ + contents.last.mode
191
+ + # => "040000"
192
+ +
193
+ +There is a convenience method that allows you to get a named sub-object
194
+ +from a tree.
195
+ +
196
+ + tree/"lib"
197
+ + # => #<Grit::Tree "e74893a3d8a25cbb1367cf241cc741bfd503c4b2">
198
+ +
199
+ +You can also get a tree directly from the repo if you know its name.
200
+ +
201
+ + repo.tree
202
+ + # => #<Grit::Tree "master">
203
+ +
204
+ + repo.tree("91169e1f5fa4de2eaea3f176461f5dc784796769")
205
+ + # => #<Grit::Tree "91169e1f5fa4de2eaea3f176461f5dc784796769">
206
+ +
207
+ += The Blob object
208
+ +
209
+ +A blob represents a file. Trees often contain blobs.
210
+ +
211
+ + blob = tree.contents.first
212
+ + # => #<Grit::Blob "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666">
213
+ +
214
+ +A blob has certain attributes.
215
+ +
216
+ + blob.id
217
+ + # => "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666"
218
+ +
219
+ + blob.name
220
+ + # => "README.txt"
221
+ +
222
+ + blob.mode
223
+ + # => "100644"
224
+ +
225
+ + blob.size
226
+ + # => 7726
227
+ +
228
+ +You can get the data of a blob as a string.
229
+ +
230
+ + blob.data
231
+ + # => "Grit is a library to ..."
232
+ +
233
+ +You can also get a blob directly from the repo if you know its name.
234
+
235
+ -* FIX (sudo gem install, anything else)
236
+ + repo.blob("4ebc8aea50e0a67e000ba29a30809d0a7b9b2666")
237
+ + # => #<Grit::Blob "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666">
238
+
239
+ == LICENSE:
240
+
241
+ (The MIT License)
242
+
243
+ -Copyright (c) 2007 FIX
244
+ +Copyright (c) 2007 Tom Preston-Werner
245
+
246
+ Permission is hereby granted, free of charge, to any person obtaining
247
+ a copy of this software and associated documentation files (the
248
+ diff --git a/Rakefile b/Rakefile
249
+ index 5bfb62163af455ca54422fd0b2e723ba1021ad12..72fde8c9ca87a1c992ce992bab13c3c4f13cddb9 100644
250
+ --- a/Rakefile
251
+ +++ b/Rakefile
252
+ @@ -4,11 +4,11 @@ require './lib/grit.rb'
253
+
254
+ Hoe.new('grit', Grit::VERSION) do |p|
255
+ p.rubyforge_name = 'grit'
256
+ - # p.author = 'FIX'
257
+ - # p.email = 'FIX'
258
+ - # p.summary = 'FIX'
259
+ - # p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
260
+ - # p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
261
+ + p.author = 'Tom Preston-Werner'
262
+ + p.email = 'tom@rubyisawesome.com'
263
+ + p.summary = 'Object model interface to a git repo'
264
+ + p.description = p.paragraphs_of('README.txt', 2..2).join("\n\n")
265
+ + p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[2..-1].map { |u| u.strip }
266
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
267
+ end
268
+
269
+ diff --git a/lib/grit.rb b/lib/grit.rb
270
+ index ae0792ae39d4891ebc1af996102a4f9df703394d..ae55fd7961ac49233f6ca515622a61e90d516044 100644
271
+ --- a/lib/grit.rb
272
+ +++ b/lib/grit.rb
273
+ @@ -1,4 +1,4 @@
274
+ -$:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
275
+ +$:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
276
+
277
+ # core
278
+
279
+ @@ -12,6 +12,8 @@ require 'grit/head'
280
+ require 'grit/commit'
281
+ require 'grit/tree'
282
+ require 'grit/blob'
283
+ +require 'grit/actor'
284
+ +require 'grit/diff'
285
+ require 'grit/repo'
286
+
287
+ module Grit
288
+ @@ -21,5 +23,5 @@ module Grit
289
+
290
+ self.debug = false
291
+
292
+ - VERSION = '1.0.0'
293
+ + VERSION = '0.1.0'
294
+ end
295
+
296
+ diff --git a/lib/grit/actor.rb b/lib/grit/actor.rb
297
+ new file mode 100644
298
+ index 0000000000000000000000000000000000000000..f733bce6b57c0e5e353206e692b0e3105c2527f4
299
+ --- /dev/null
300
+ +++ b/lib/grit/actor.rb
301
+ @@ -0,0 +1,35 @@
302
+ +module Grit
303
+ +
304
+ + class Actor
305
+ + attr_reader :name
306
+ + attr_reader :email
307
+ +
308
+ + def initialize(name, email)
309
+ + @name = name
310
+ + @email = email
311
+ + end
312
+ +
313
+ + # Create an Actor from a string.
314
+ + # +str+ is the string, which is expected to be in regular git format
315
+ + #
316
+ + # Format
317
+ + # John Doe <jdoe@example.com>
318
+ + #
319
+ + # Returns Actor
320
+ + def self.from_string(str)
321
+ + case str
322
+ + when /<.+>/
323
+ + m, name, email = *str.match(/(.*) <(.+?)>/)
324
+ + return self.new(name, email)
325
+ + else
326
+ + return self.new(str, nil)
327
+ + end
328
+ + end
329
+ +
330
+ + # Pretty object inspection
331
+ + def inspect
332
+ + %Q{#<Grit::Actor "#{@name} <#{@email}>">}
333
+ + end
334
+ + end # Actor
335
+ +
336
+ +end # Grit
337
+
338
+ diff --git a/lib/grit/blob.rb b/lib/grit/blob.rb
339
+ index c863646d4278bfee2a7bcb64caace6b31f89ef03..87d43fab37844afdc2f8814dba3abdaa791f1370 100644
340
+ --- a/lib/grit/blob.rb
341
+ +++ b/lib/grit/blob.rb
342
+ @@ -81,9 +81,9 @@ module Grit
343
+ c = commits[info[:id]]
344
+ unless c
345
+ c = Commit.create(repo, :id => info[:id],
346
+ - :author => info[:author],
347
+ + :author => Actor.from_string(info[:author] + ' ' + info[:author_email]),
348
+ :authored_date => info[:author_date],
349
+ - :committer => info[:committer],
350
+ + :committer => Actor.from_string(info[:committer] + ' ' + info[:committer_email]),
351
+ :committed_date => info[:committer_date],
352
+ :message => info[:summary])
353
+ commits[info[:id]] = c
354
+ @@ -102,11 +102,6 @@ module Grit
355
+ def inspect
356
+ %Q{#<Grit::Blob "#{@id}">}
357
+ end
358
+ -
359
+ - # private
360
+ -
361
+ - def self.read_
362
+ - end
363
+ end # Blob
364
+
365
+ end # Grit
366
+
367
+ diff --git a/lib/grit/commit.rb b/lib/grit/commit.rb
368
+ index c2a9e2f81657b19925fe9bab4bc5d7ac130e5880..cd9c3e3184c97e83a8982fab9499cad3aec339f6 100644
369
+ --- a/lib/grit/commit.rb
370
+ +++ b/lib/grit/commit.rb
371
+ @@ -136,6 +136,11 @@ module Grit
372
+ commits
373
+ end
374
+
375
+ + def self.diff(repo, id)
376
+ + text = repo.git.diff({:full_index => true}, id)
377
+ + Diff.list_from_string(repo, text)
378
+ + end
379
+ +
380
+ # Convert this Commit to a String which is just the SHA1 id
381
+ def to_s
382
+ @id
383
+ @@ -153,7 +158,7 @@ module Grit
384
+ # Returns [String (actor name and email), Time (acted at time)]
385
+ def self.actor(line)
386
+ m, actor, epoch = *line.match(/^.+? (.*) (\d+) .*$/)
387
+ - [actor, Time.at(epoch.to_i)]
388
+ + [Actor.from_string(actor), Time.at(epoch.to_i)]
389
+ end
390
+ end # Commit
391
+
392
+ diff --git a/lib/grit/git.rb b/lib/grit/git.rb
393
+ index 1d5251d40fb65ac89184ec662a3e1b04d0c24861..98eeddda5ed2b0e215e21128112393bdc9bc9039 100644
394
+ --- a/lib/grit/git.rb
395
+ +++ b/lib/grit/git.rb
396
+ @@ -13,17 +13,6 @@ module Grit
397
+ self.git_dir = git_dir
398
+ end
399
+
400
+ - # Converstion hash from Ruby style options to git command line
401
+ - # style options
402
+ - TRANSFORM = {:max_count => "--max-count=",
403
+ - :skip => "--skip=",
404
+ - :pretty => "--pretty=",
405
+ - :sort => "--sort=",
406
+ - :format => "--format=",
407
+ - :since => "--since=",
408
+ - :p => "-p",
409
+ - :s => "-s"}
410
+ -
411
+ # Run the given git command with the specified arguments and return
412
+ # the result as a String
413
+ # +cmd+ is the command
414
+ @@ -52,12 +41,19 @@ module Grit
415
+ def transform_options(options)
416
+ args = []
417
+ options.keys.each do |opt|
418
+ - if TRANSFORM[opt]
419
+ + if opt.to_s.size == 1
420
+ + if options[opt] == true
421
+ + args << "-#{opt}"
422
+ + else
423
+ + val = options.delete(opt)
424
+ + args << "-#{opt.to_s} #{val}"
425
+ + end
426
+ + else
427
+ if options[opt] == true
428
+ - args << TRANSFORM[opt]
429
+ + args << "--#{opt.to_s.gsub(/_/, '-')}"
430
+ else
431
+ val = options.delete(opt)
432
+ - args << TRANSFORM[opt] + val.to_s
433
+ + args << "--#{opt.to_s.gsub(/_/, '-')}=#{val}"
434
+ end
435
+ end
436
+ end
437
+ diff --git a/lib/grit/repo.rb b/lib/grit/repo.rb
438
+ index 624991d07e240ae66ff2a0dc55e2f2b5e262c75b..63bf03b839374c96a3d42a07d56681a797f52a71 100644
439
+ --- a/lib/grit/repo.rb
440
+ +++ b/lib/grit/repo.rb
441
+ @@ -93,6 +93,17 @@ module Grit
442
+ def blob(id)
443
+ Blob.create(self, :id => id)
444
+ end
445
+ +
446
+ + # The commit log for a treeish
447
+ + #
448
+ + # Returns Grit::Commit[]
449
+ + def log(commit = 'master', path = nil, options = {})
450
+ + default_options = {:pretty => "raw"}
451
+ + actual_options = default_options.merge(options)
452
+ + arg = path ? "#{commit} -- #{path}" : commit
453
+ + commits = self.git.log(actual_options, arg)
454
+ + Commit.list_from_string(self, commits)
455
+ + end
456
+
457
+ # The diff from commit +a+ to commit +b+, optionally restricted to the given file(s)
458
+ # +a+ is the base commit
459
+ @@ -121,4 +132,4 @@ module Grit
460
+ end
461
+ end # Repo
462
+
463
+ -end # Grit
464
+
465
+ +end # Grit
466
+ diff --git a/test/test_actor.rb b/test/test_actor.rb
467
+ new file mode 100644
468
+ index 0000000000000000000000000000000000000000..08391f12336831d048122c8d13bc8404f27e6b91
469
+ --- /dev/null
470
+ +++ b/test/test_actor.rb
471
+ @@ -0,0 +1,28 @@
472
+ +require File.dirname(__FILE__) + '/helper'
473
+ +
474
+ +class TestActor < Test::Unit::TestCase
475
+ + def setup
476
+ +
477
+ + end
478
+ +
479
+ + # from_string
480
+ +
481
+ + def test_from_string_should_separate_name_and_email
482
+ + a = Actor.from_string("Tom Werner <tom@example.com>")
483
+ + assert_equal "Tom Werner", a.name
484
+ + assert_equal "tom@example.com", a.email
485
+ + end
486
+ +
487
+ + def test_from_string_should_handle_just_name
488
+ + a = Actor.from_string("Tom Werner")
489
+ + assert_equal "Tom Werner", a.name
490
+ + assert_equal nil, a.email
491
+ + end
492
+ +
493
+ + # inspect
494
+ +
495
+ + def test_inspect
496
+ + a = Actor.from_string("Tom Werner <tom@example.com>")
497
+ + assert_equal %Q{#<Grit::Actor "Tom Werner <tom@example.com>">}, a.inspect
498
+ + end
499
+ +end
500
+
501
+ diff --git a/test/test_blob.rb b/test/test_blob.rb
502
+ index 6fa087d785661843034d03c7e0b917a8a80d5d8c..9ef84cc14266141b070771706b8aeebc3dfbef82 100644
503
+ --- a/test/test_blob.rb
504
+ +++ b/test/test_blob.rb
505
+ @@ -40,9 +40,11 @@ class TestBlob < Test::Unit::TestCase
506
+ c = b.first.first
507
+ c.expects(:__bake__).times(0)
508
+ assert_equal '634396b2f541a9f2d58b00be1a07f0c358b999b3', c.id
509
+ - assert_equal 'Tom Preston-Werner', c.author
510
+ + assert_equal 'Tom Preston-Werner', c.author.name
511
+ + assert_equal 'tom@mojombo.com', c.author.email
512
+ assert_equal Time.at(1191997100), c.authored_date
513
+ - assert_equal 'Tom Preston-Werner', c.committer
514
+ + assert_equal 'Tom Preston-Werner', c.committer.name
515
+ + assert_equal 'tom@mojombo.com', c.committer.email
516
+ assert_equal Time.at(1191997100), c.committed_date
517
+ assert_equal 'initial grit setup', c.message
518
+ # c.expects(:__bake__).times(1)
519
+ diff --git a/test/test_commit.rb b/test/test_commit.rb
520
+ index 3bd6af75deda05725900eb7fd06e8107df14c655..0936c90e5b29ede2b5214d6dc26d256a8c6646f4 100644
521
+ --- a/test/test_commit.rb
522
+ +++ b/test/test_commit.rb
523
+ @@ -10,9 +10,28 @@ class TestCommit < Test::Unit::TestCase
524
+ def test_bake
525
+ Git.any_instance.expects(:rev_list).returns(fixture('rev_list_single'))
526
+ @c = Commit.create(@r, :id => '4c8124ffcf4039d292442eeccabdeca5af5c5017')
527
+ - @c.author # cause bake-age
528
+ + @c.author # bake
529
+
530
+ - assert_equal "Tom Preston-Werner <tom@mojombo.com>", @c.author
531
+ + assert_equal "Tom Preston-Werner", @c.author.name
532
+ + assert_equal "tom@mojombo.com", @c.author.email
533
+ + end
534
+ +
535
+ + # diff
536
+ +
537
+ + def test_diff
538
+ + Git.any_instance.expects(:diff).returns(fixture('diff_p'))
539
+ + diffs = Commit.diff(@r, 'master')
540
+ +
541
+ + assert_equal 15, diffs.size
542
+ +
543
+ + assert_equal '.gitignore', diffs.first.a_path
544
+ + assert_equal '.gitignore', diffs.first.b_path
545
+ + assert_equal '4ebc8ae', diffs.first.a_commit
546
+ + assert_equal '2dd0253', diffs.first.b_commit
547
+ + assert_equal '100644', diffs.first.mode
548
+ + assert_equal false, diffs.first.new_file
549
+ + assert_equal false, diffs.first.deleted_file
550
+ + assert_equal "--- a/.gitignore\n+++ b/.gitignore\n@@ -1 +1,2 @@\n coverage\n+pkg", diffs.first.diff
551
+ end
552
+
553
+ # to_s
554
+ diff --git a/test/test_git.rb b/test/test_git.rb
555
+ index e615a035d096b6cbc984e2f4213c06d0ac785321..72a18ec424f078f6daee75dbc62265c02ba7a892 100644
556
+ --- a/test/test_git.rb
557
+ +++ b/test/test_git.rb
558
+ @@ -10,6 +10,12 @@ class TestGit < Test::Unit::TestCase
559
+ end
560
+
561
+ def test_transform_options
562
+ + assert_equal ["-s"], @git.transform_options({:s => true})
563
+ + assert_equal ["-s 5"], @git.transform_options({:s => 5})
564
+ +
565
+ + assert_equal ["--max-count"], @git.transform_options({:max_count => true})
566
+ assert_equal ["--max-count=5"], @git.transform_options({:max_count => 5})
567
+ +
568
+ + assert_equal ["-t", "-s"], @git.transform_options({:s => true, :t => true})
569
+ end
570
+ end
571
+
572
+ diff --git a/test/test_repo.rb b/test/test_repo.rb
573
+ index d53476a51e3286be270c7b515ec1d65e5c1716e0..114a4464fa248550be10cc4abe0735d6025b5fca 100644
574
+ --- a/test/test_repo.rb
575
+ +++ b/test/test_repo.rb
576
+ @@ -59,9 +59,11 @@ class TestRepo < Test::Unit::TestCase
577
+ assert_equal '4c8124ffcf4039d292442eeccabdeca5af5c5017', c.id
578
+ assert_equal ["634396b2f541a9f2d58b00be1a07f0c358b999b3"], c.parents.map { |p| p.id }
579
+ assert_equal "672eca9b7f9e09c22dcb128c283e8c3c8d7697a4", c.tree.id
580
+ - assert_equal "Tom Preston-Werner <tom@mojombo.com>", c.author
581
+ + assert_equal "Tom Preston-Werner", c.author.name
582
+ + assert_equal "tom@mojombo.com", c.author.email
583
+ assert_equal Time.at(1191999972), c.authored_date
584
+ - assert_equal "Tom Preston-Werner <tom@mojombo.com>", c.committer
585
+ + assert_equal "Tom Preston-Werner", c.committer.name
586
+ + assert_equal "tom@mojombo.com", c.committer.email
587
+ assert_equal Time.at(1191999972), c.committed_date
588
+ assert_equal "implement Grit#heads", c.message
589
+
590
+ @@ -125,4 +127,18 @@ class TestRepo < Test::Unit::TestCase
591
+ def test_inspect
592
+ assert_equal %Q{#<Grit::Repo "#{File.expand_path(GRIT_REPO)}/.git">}, @r.inspect
593
+ end
594
+ -end
595
+
596
+ +
597
+ + # log
598
+ +
599
+ + def test_log
600
+ + Git.any_instance.expects(:log).times(2).with({:pretty => 'raw'}, 'master').returns(fixture('rev_list'))
601
+ +
602
+ + assert_equal '4c8124ffcf4039d292442eeccabdeca5af5c5017', @r.log.first.id
603
+ + assert_equal 'ab25fd8483882c3bda8a458ad2965d2248654335', @r.log.last.id
604
+ + end
605
+ +
606
+ + def test_log_with_path_and_options
607
+ + Git.any_instance.expects(:log).with({:pretty => 'raw', :max_count => 1}, 'master -- file.rb').returns(fixture('rev_list'))
608
+ + @r.log('master', 'file.rb', :max_count => 1)
609
+ + end
610
+ +end