This file is indexed.

/usr/lib/python3/dist-packages/git/test/fixtures/diff_p is in python3-git 2.1.1-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

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