relevance-grit 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/History.txt +6 -0
  2. data/Manifest.txt +56 -0
  3. data/README.txt +213 -0
  4. data/Rakefile +29 -0
  5. data/grit.gemspec +16 -0
  6. data/lib/grit/actor.rb +36 -0
  7. data/lib/grit/blob.rb +117 -0
  8. data/lib/grit/commit.rb +208 -0
  9. data/lib/grit/config.rb +44 -0
  10. data/lib/grit/diff.rb +70 -0
  11. data/lib/grit/errors.rb +7 -0
  12. data/lib/grit/git.rb +124 -0
  13. data/lib/grit/index.rb +77 -0
  14. data/lib/grit/lazy.rb +31 -0
  15. data/lib/grit/ref.rb +110 -0
  16. data/lib/grit/repo.rb +318 -0
  17. data/lib/grit/tree.rb +99 -0
  18. data/lib/grit.rb +42 -0
  19. data/test/fixtures/blame +131 -0
  20. data/test/fixtures/cat_file_blob +1 -0
  21. data/test/fixtures/cat_file_blob_size +1 -0
  22. data/test/fixtures/diff_2 +54 -0
  23. data/test/fixtures/diff_2f +19 -0
  24. data/test/fixtures/diff_f +15 -0
  25. data/test/fixtures/diff_i +201 -0
  26. data/test/fixtures/diff_mode_only +1152 -0
  27. data/test/fixtures/diff_new_mode +17 -0
  28. data/test/fixtures/diff_p +610 -0
  29. data/test/fixtures/for_each_ref +0 -0
  30. data/test/fixtures/for_each_ref_remotes +0 -0
  31. data/test/fixtures/for_each_ref_tags +0 -0
  32. data/test/fixtures/ls_tree_a +7 -0
  33. data/test/fixtures/ls_tree_b +2 -0
  34. data/test/fixtures/ls_tree_commit +3 -0
  35. data/test/fixtures/rev_list +26 -0
  36. data/test/fixtures/rev_list_count +655 -0
  37. data/test/fixtures/rev_list_single +7 -0
  38. data/test/fixtures/rev_parse +1 -0
  39. data/test/fixtures/show_empty_commit +6 -0
  40. data/test/fixtures/simple_config +2 -0
  41. data/test/helper.rb +17 -0
  42. data/test/profile.rb +21 -0
  43. data/test/suite.rb +6 -0
  44. data/test/test_actor.rb +35 -0
  45. data/test/test_blob.rb +74 -0
  46. data/test/test_commit.rb +182 -0
  47. data/test/test_config.rb +58 -0
  48. data/test/test_diff.rb +18 -0
  49. data/test/test_git.rb +52 -0
  50. data/test/test_grit.rb +32 -0
  51. data/test/test_head.rb +22 -0
  52. data/test/test_real.rb +19 -0
  53. data/test/test_reality.rb +17 -0
  54. data/test/test_remote.rb +15 -0
  55. data/test/test_repo.rb +278 -0
  56. data/test/test_tag.rb +29 -0
  57. data/test/test_tree.rb +91 -0
  58. metadata +133 -0
data/lib/grit/repo.rb ADDED
@@ -0,0 +1,318 @@
1
+ module Grit
2
+
3
+ class Repo
4
+ DAEMON_EXPORT_FILE = 'git-daemon-export-ok'
5
+
6
+ # The path of the git repo as a String
7
+ attr_accessor :path
8
+ attr_reader :bare
9
+
10
+ # The git command line interface object
11
+ attr_accessor :git
12
+
13
+ # Create a new Repo instance
14
+ # +path+ is the path to either the root git directory or the bare git repo
15
+ #
16
+ # Examples
17
+ # g = Repo.new("/Users/tom/dev/grit")
18
+ # g = Repo.new("/Users/tom/public/grit.git")
19
+ #
20
+ # Returns Grit::Repo
21
+ def initialize(path)
22
+ epath = File.expand_path(path)
23
+
24
+ if File.exist?(File.join(epath, '.git'))
25
+ self.path = File.join(epath, '.git')
26
+ @bare = false
27
+ elsif File.exist?(epath) && epath =~ /\.git$/
28
+ self.path = epath
29
+ @bare = true
30
+ elsif File.exist?(epath)
31
+ raise InvalidGitRepositoryError.new(epath)
32
+ else
33
+ raise NoSuchPathError.new(epath)
34
+ end
35
+
36
+ self.git = Git.new(self.path)
37
+ end
38
+
39
+ # The project's description. Taken verbatim from GIT_REPO/description
40
+ #
41
+ # Returns String
42
+ def description
43
+ File.open(File.join(self.path, 'description')).read.chomp
44
+ end
45
+
46
+ # An array of Head objects representing the branch heads in
47
+ # this repo
48
+ #
49
+ # Returns Grit::Head[] (baked)
50
+ def heads
51
+ Head.find_all(self)
52
+ end
53
+
54
+ alias_method :branches, :heads
55
+
56
+ # Object reprsenting the current repo head.
57
+ #
58
+ # Returns Grit::Head (baked)
59
+ def head
60
+ Head.current(self)
61
+ end
62
+
63
+ # An array of Tag objects that are available in this repo
64
+ #
65
+ # Returns Grit::Tag[] (baked)
66
+ def tags
67
+ Tag.find_all(self)
68
+ end
69
+
70
+ # An array of Remote objects representing the remote branches in
71
+ # this repo
72
+ #
73
+ # Returns Grit::Remote[] (baked)
74
+ def remotes
75
+ Remote.find_all(self)
76
+ end
77
+
78
+ # An array of Ref objects representing the refs in
79
+ # this repo
80
+ #
81
+ # Returns Grit::Ref[] (baked)
82
+ def refs
83
+ [ Head.find_all(self), Tag.find_all(self), Remote.find_all(self) ].flatten
84
+ end
85
+
86
+ # An array of Commit objects representing the history of a given ref/commit
87
+ # +start+ is the branch/commit name (default 'master')
88
+ # +max_count+ is the maximum number of commits to return (default 10)
89
+ # +skip+ is the number of commits to skip (default 0)
90
+ #
91
+ # Returns Grit::Commit[] (baked)
92
+ def commits(start = 'master', max_count = 10, skip = 0)
93
+ options = {:max_count => max_count,
94
+ :skip => skip}
95
+
96
+ Commit.find_all(self, start, options)
97
+ end
98
+
99
+ # The Commits objects that are reachable via +to+ but not via +from+
100
+ # Commits are returned in chronological order.
101
+ # +from+ is the branch/commit name of the younger item
102
+ # +to+ is the branch/commit name of the older item
103
+ #
104
+ # Returns Grit::Commit[] (baked)
105
+ def commits_between(from, to)
106
+ Commit.find_all(self, "#{from}..#{to}").reverse
107
+ end
108
+
109
+ # The Commits objects that are newer than the specified date.
110
+ # Commits are returned in chronological order.
111
+ # +start+ is the branch/commit name (default 'master')
112
+ # +since+ is a string represeting a date/time
113
+ # +extra_options+ is a hash of extra options
114
+ #
115
+ # Returns Grit::Commit[] (baked)
116
+ def commits_since(start = 'master', since = '1970-01-01', extra_options = {})
117
+ options = {:since => since}.merge(extra_options)
118
+
119
+ Commit.find_all(self, start, options)
120
+ end
121
+
122
+ # The number of commits reachable by the given branch/commit
123
+ # +start+ is the branch/commit name (default 'master')
124
+ #
125
+ # Returns Integer
126
+ def commit_count(start = 'master')
127
+ Commit.count(self, start)
128
+ end
129
+
130
+ # The Commit object for the specified id
131
+ # +id+ is the SHA1 identifier of the commit
132
+ #
133
+ # Returns Grit::Commit (baked)
134
+ def commit(id)
135
+ options = {:max_count => 1}
136
+
137
+ Commit.find_all(self, id, options).first
138
+ end
139
+
140
+ # The Tree object for the given treeish reference
141
+ # +treeish+ is the reference (default 'master')
142
+ # +paths+ is an optional Array of directory paths to restrict the tree (deafult [])
143
+ #
144
+ # Examples
145
+ # repo.tree('master', ['lib/'])
146
+ #
147
+ # Returns Grit::Tree (baked)
148
+ def tree(treeish = 'master', paths = [])
149
+ Tree.construct(self, treeish, paths)
150
+ end
151
+
152
+ # The Blob object for the given id
153
+ # +id+ is the SHA1 id of the blob
154
+ #
155
+ # Returns Grit::Blob (unbaked)
156
+ def blob(id)
157
+ Blob.create(self, :id => id)
158
+ end
159
+
160
+ # The commit log for a treeish
161
+ #
162
+ # Returns Grit::Commit[]
163
+ def log(commit = 'master', path = nil, options = {})
164
+ default_options = {:pretty => "raw"}
165
+ actual_options = default_options.merge(options)
166
+ arg = path ? [commit, '--', path] : [commit]
167
+ commits = self.git.log(actual_options, *arg)
168
+ Commit.list_from_string(self, commits)
169
+ end
170
+
171
+ # The diff from commit +a+ to commit +b+, optionally restricted to the given file(s)
172
+ # +a+ is the base commit
173
+ # +b+ is the other commit
174
+ # +paths+ is an optional list of file paths on which to restrict the diff
175
+ def diff(a, b, *paths)
176
+ self.git.diff({}, a, b, '--', *paths)
177
+ end
178
+
179
+ # The commit diff for the given commit
180
+ # +commit+ is the commit name/id
181
+ #
182
+ # Returns Grit::Diff[]
183
+ def commit_diff(commit)
184
+ Commit.diff(self, commit)
185
+ end
186
+
187
+ # Initialize a bare git repository at the given path
188
+ # +path+ is the full path to the repo (traditionally ends with /<name>.git)
189
+ # +options+ is any additional options to the git init command
190
+ #
191
+ # Examples
192
+ # Grit::Repo.init_bare('/var/git/myrepo.git')
193
+ #
194
+ # Returns Grit::Repo (the newly created repo)
195
+ def self.init_bare(path, options = {})
196
+ git = Git.new(path)
197
+ git.init(options)
198
+ self.new(path)
199
+ end
200
+
201
+ # Fork a bare git repository from this repo
202
+ # +path+ is the full path of the new repo (traditionally ends with /<name>.git)
203
+ # +options+ is any additional options to the git clone command
204
+ #
205
+ # Returns Grit::Repo (the newly forked repo)
206
+ def fork_bare(path, options = {})
207
+ default_options = {:bare => true, :shared => true}
208
+ real_options = default_options.merge(options)
209
+ self.git.clone(real_options, self.path, path)
210
+ Repo.new(path)
211
+ end
212
+
213
+ # Archive the given treeish
214
+ # +treeish+ is the treeish name/id (default 'master')
215
+ # +prefix+ is the optional prefix
216
+ #
217
+ # Examples
218
+ # repo.archive_tar
219
+ # # => <String containing tar archive>
220
+ #
221
+ # repo.archive_tar('a87ff14')
222
+ # # => <String containing tar archive for commit a87ff14>
223
+ #
224
+ # repo.archive_tar('master', 'myproject/')
225
+ # # => <String containing tar archive and prefixed with 'myproject/'>
226
+ #
227
+ # Returns String (containing tar archive)
228
+ def archive_tar(treeish = 'master', prefix = nil)
229
+ options = {}
230
+ options[:prefix] = prefix if prefix
231
+ self.git.archive(options, treeish)
232
+ end
233
+
234
+ # Archive and gzip the given treeish
235
+ # +treeish+ is the treeish name/id (default 'master')
236
+ # +prefix+ is the optional prefix
237
+ #
238
+ # Examples
239
+ # repo.archive_tar_gz
240
+ # # => <String containing tar.gz archive>
241
+ #
242
+ # repo.archive_tar_gz('a87ff14')
243
+ # # => <String containing tar.gz archive for commit a87ff14>
244
+ #
245
+ # repo.archive_tar_gz('master', 'myproject/')
246
+ # # => <String containing tar.gz archive and prefixed with 'myproject/'>
247
+ #
248
+ # Returns String (containing tar.gz archive)
249
+ def archive_tar_gz(treeish = 'master', prefix = nil)
250
+ options = {}
251
+ options[:prefix] = prefix if prefix
252
+ self.git.archive(options, treeish, "| gzip")
253
+ end
254
+
255
+ # Enable git-daemon serving of this repository by writing the
256
+ # git-daemon-export-ok file to its git directory
257
+ #
258
+ # Returns nothing
259
+ def enable_daemon_serve
260
+ FileUtils.touch(File.join(self.path, DAEMON_EXPORT_FILE))
261
+ end
262
+
263
+ # Disable git-daemon serving of this repository by ensuring there is no
264
+ # git-daemon-export-ok file in its git directory
265
+ #
266
+ # Returns nothing
267
+ def disable_daemon_serve
268
+ FileUtils.rm_f(File.join(self.path, DAEMON_EXPORT_FILE))
269
+ end
270
+
271
+ # The list of alternates for this repo
272
+ #
273
+ # Returns Array[String] (pathnames of alternates)
274
+ def alternates
275
+ alternates_path = File.join(self.path, *%w{objects info alternates})
276
+
277
+ if File.exist?(alternates_path)
278
+ File.read(alternates_path).strip.split("\n")
279
+ else
280
+ []
281
+ end
282
+ end
283
+
284
+ # Sets the alternates
285
+ # +alts+ is the Array of String paths representing the alternates
286
+ #
287
+ # Returns nothing
288
+ def alternates=(alts)
289
+ alts.each do |alt|
290
+ unless File.exist?(alt)
291
+ raise "Could not set alternates. Alternate path #{alt} must exist"
292
+ end
293
+ end
294
+
295
+ if alts.empty?
296
+ File.delete(File.join(self.path, *%w{objects info alternates}))
297
+ else
298
+ File.open(File.join(self.path, *%w{objects info alternates}), 'w') do |f|
299
+ f.write alts.join("\n")
300
+ end
301
+ end
302
+ end
303
+
304
+ def config
305
+ @config ||= Config.new(self)
306
+ end
307
+
308
+ def index
309
+ Index.new(self)
310
+ end
311
+
312
+ # Pretty object inspection
313
+ def inspect
314
+ %Q{#<Grit::Repo "#{@path}">}
315
+ end
316
+ end # Repo
317
+
318
+ end # Grit
data/lib/grit/tree.rb ADDED
@@ -0,0 +1,99 @@
1
+ module Grit
2
+
3
+ class Tree
4
+ lazy_reader :contents
5
+ attr_reader :id
6
+ attr_reader :mode
7
+ attr_reader :name
8
+
9
+ # Construct the contents of the tree
10
+ # +repo+ is the Repo
11
+ # +treeish+ is the reference
12
+ # +paths+ is an optional Array of directory paths to restrict the tree
13
+ #
14
+ # Returns Grit::Tree (baked)
15
+ def self.construct(repo, treeish, paths = [])
16
+ output = repo.git.ls_tree({}, treeish, *paths)
17
+
18
+ self.allocate.construct_initialize(repo, treeish, output)
19
+ end
20
+
21
+ def construct_initialize(repo, id, text)
22
+ @repo = repo
23
+ @id = id
24
+ @contents = []
25
+
26
+ text.split("\n").each do |line|
27
+ @contents << content_from_string(repo, line)
28
+ end
29
+ @contents.compact!
30
+
31
+ self
32
+ end
33
+
34
+ def lazy_source
35
+ Tree.construct(@repo, @id, [])
36
+ end
37
+
38
+ # Create an unbaked Tree containing just the specified attributes
39
+ # +repo+ is the Repo
40
+ # +atts+ is a Hash of instance variable data
41
+ #
42
+ # Returns Grit::Tree (unbaked)
43
+ def self.create(repo, atts)
44
+ self.allocate.create_initialize(repo, atts)
45
+ end
46
+
47
+ # Initializer for Tree.create
48
+ # +repo+ is the Repo
49
+ # +atts+ is a Hash of instance variable data
50
+ #
51
+ # Returns Grit::Tree (unbaked)
52
+ def create_initialize(repo, atts)
53
+ @repo = repo
54
+
55
+ atts.each do |k, v|
56
+ instance_variable_set("@#{k}", v)
57
+ end
58
+ self
59
+ end
60
+
61
+ # Parse a content item and create the appropriate object
62
+ # +repo+ is the Repo
63
+ # +text+ is the single line containing the items data in `git ls-tree` format
64
+ #
65
+ # Returns Grit::Blob or Grit::Tree
66
+ def content_from_string(repo, text)
67
+ mode, type, id, name = text.split(" ", 4)
68
+ case type
69
+ when "tree"
70
+ Tree.create(repo, :id => id, :mode => mode, :name => name)
71
+ when "blob"
72
+ Blob.create(repo, :id => id, :mode => mode, :name => name)
73
+ when "commit"
74
+ nil
75
+ else
76
+ raise "Invalid type: #{type}"
77
+ end
78
+ end
79
+
80
+ # Find the named object in this tree's contents
81
+ #
82
+ # Examples
83
+ # Repo.new('/path/to/grit').tree/'lib'
84
+ # # => #<Grit::Tree "6cc23ee138be09ff8c28b07162720018b244e95e">
85
+ # Repo.new('/path/to/grit').tree/'README.txt'
86
+ # # => #<Grit::Blob "8b1e02c0fb554eed2ce2ef737a68bb369d7527df">
87
+ #
88
+ # Returns Grit::Blob or Grit::Tree or nil if not found
89
+ def /(file)
90
+ self.contents.select { |c| c.name == file }.first
91
+ end
92
+
93
+ # Pretty object inspection
94
+ def inspect
95
+ %Q{#<Grit::Tree "#{@id}">}
96
+ end
97
+ end # Tree
98
+
99
+ end # Grit
data/lib/grit.rb ADDED
@@ -0,0 +1,42 @@
1
+ $:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
2
+
3
+ # core
4
+ require 'fileutils'
5
+ require 'time'
6
+
7
+ # stdlib
8
+ require 'timeout'
9
+ require 'logger'
10
+
11
+ # third party
12
+ require 'rubygems'
13
+ require 'mime/types'
14
+ require 'open4'
15
+
16
+ # internal requires
17
+ require 'grit/lazy'
18
+ require 'grit/errors'
19
+ require 'grit/git'
20
+ require 'grit/ref'
21
+ require 'grit/commit'
22
+ require 'grit/tree'
23
+ require 'grit/blob'
24
+ require 'grit/actor'
25
+ require 'grit/diff'
26
+ require 'grit/config'
27
+ require 'grit/repo'
28
+ require 'grit/index'
29
+
30
+ module Grit
31
+ class << self
32
+ attr_accessor :debug
33
+ attr_accessor :logger
34
+ def log(str)
35
+ logger.debug { str }
36
+ end
37
+ end
38
+ self.debug = false
39
+ @logger ||= ::Logger.new(STDOUT)
40
+
41
+ VERSION = '0.8.1'
42
+ end
@@ -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,54 @@
1
+ diff --git a/lib/grit/commit.rb b/lib/grit/commit.rb
2
+ index a093bb1db8e884cccf396b297259181d1caebed4..80fd3d527f269ecbd570b65b8e21fd85baedb6e9 100644
3
+ --- a/lib/grit/commit.rb
4
+ +++ b/lib/grit/commit.rb
5
+ @@ -156,12 +156,8 @@ module Grit
6
+
7
+ def diffs
8
+ if parents.empty?
9
+ - diff = @repo.git.show({:full_index => true, :pretty => 'raw'}, @id)
10
+ - if diff =~ /diff --git a/
11
+ - diff = diff.sub(/.+?(diff --git a)/m, '\1')
12
+ - else
13
+ - diff = ''
14
+ - end
15
+ + diff = @repo.git.show({:full_index => true, :pretty => 'raw'}, @id)
16
+ + diff = diff.sub(/.+?(diff --git a)/m, '\1')
17
+ Diff.list_from_string(@repo, diff)
18
+ else
19
+ self.class.diff(@repo, parents.first.id, @id)
20
+ diff --git a/test/fixtures/show_empty_commit b/test/fixtures/show_empty_commit
21
+ deleted file mode 100644
22
+ index ea25e32a409fdf74c1b9268820108d1c16dcc553..0000000000000000000000000000000000000000
23
+ --- a/test/fixtures/show_empty_commit
24
+ +++ /dev/null
25
+ @@ -1,6 +0,0 @@
26
+ -commit 1e3824339762bd48316fe87bfafc853732d43264
27
+ -tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904
28
+ -author Tom Preston-Werner <tom@mojombo.com> 1157392833 +0000
29
+ -committer Tom Preston-Werner <tom@mojombo.com> 1157392833 +0000
30
+ -
31
+ - initial directory structure
32
+ diff --git a/test/test_commit.rb b/test/test_commit.rb
33
+ index fdeb9000089b052f0b31a845e0173e9b089e06a0..bdbc450e08084d7d611e985cfa12fb424cab29b2 100644
34
+ --- a/test/test_commit.rb
35
+ +++ b/test/test_commit.rb
36
+ @@ -98,18 +98,6 @@ class TestCommit < Test::Unit::TestCase
37
+ assert_equal true, diffs[5].new_file
38
+ end
39
+
40
+ - def test_diffs_on_initial_import_with_empty_commit
41
+ - Git.any_instance.expects(:show).with(
42
+ - {:full_index => true, :pretty => 'raw'},
43
+ - '634396b2f541a9f2d58b00be1a07f0c358b999b3'
44
+ - ).returns(fixture('show_empty_commit'))
45
+ -
46
+ - @c = Commit.create(@r, :id => '634396b2f541a9f2d58b00be1a07f0c358b999b3')
47
+ - diffs = @c.diffs
48
+ -
49
+ - assert_equal [], diffs
50
+ - end
51
+ -
52
+ # to_s
53
+
54
+ def test_to_s
@@ -0,0 +1,19 @@
1
+ diff --git a/lib/grit/commit.rb b/lib/grit/commit.rb
2
+ index a093bb1db8e884cccf396b297259181d1caebed4..80fd3d527f269ecbd570b65b8e21fd85baedb6e9 100644
3
+ --- a/lib/grit/commit.rb
4
+ +++ b/lib/grit/commit.rb
5
+ @@ -156,12 +156,8 @@ module Grit
6
+
7
+ def diffs
8
+ if parents.empty?
9
+ - diff = @repo.git.show({:full_index => true, :pretty => 'raw'}, @id)
10
+ - if diff =~ /diff --git a/
11
+ - diff = diff.sub(/.+?(diff --git a)/m, '\1')
12
+ - else
13
+ - diff = ''
14
+ - end
15
+ + diff = @repo.git.show({:full_index => true, :pretty => 'raw'}, @id)
16
+ + diff = diff.sub(/.+?(diff --git a)/m, '\1')
17
+ Diff.list_from_string(@repo, diff)
18
+ else
19
+ self.class.diff(@repo, parents.first.id, @id)
@@ -0,0 +1,15 @@
1
+ diff --git a/lib/grit/diff.rb b/lib/grit/diff.rb
2
+ index 537955bb86a8ceaa19aea89e75ccbea5ce6f2698..00b0b4a67eca9242db5f8991e99625acd55f040c 100644
3
+ --- a/lib/grit/diff.rb
4
+ +++ b/lib/grit/diff.rb
5
+ @@ -27,6 +27,10 @@ module Grit
6
+ while !lines.empty?
7
+ m, a_path, b_path = *lines.shift.match(%r{^diff --git a/(\S+) b/(\S+)$})
8
+
9
+ + if lines.first =~ /^old mode/
10
+ + 2.times { lines.shift }
11
+ + end
12
+ +
13
+ new_file = false
14
+ deleted_file = false
15
+