mojombo-grit 0.9.4 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/API.txt +101 -0
  2. data/History.txt +38 -2
  3. data/README.md +210 -0
  4. data/VERSION.yml +4 -0
  5. data/lib/grit.rb +13 -4
  6. data/lib/grit/blame.rb +61 -0
  7. data/lib/grit/blob.rb +11 -2
  8. data/lib/grit/commit.rb +44 -31
  9. data/lib/grit/commit_stats.rb +26 -2
  10. data/lib/grit/diff.rb +6 -6
  11. data/lib/grit/git-ruby.rb +4 -2
  12. data/lib/grit/git-ruby/file_index.rb +10 -3
  13. data/lib/grit/git-ruby/git_object.rb +9 -3
  14. data/lib/grit/git-ruby/internal/{mmap.rb → file_window.rb} +2 -2
  15. data/lib/grit/git-ruby/internal/loose.rb +6 -6
  16. data/lib/grit/git-ruby/internal/pack.rb +19 -19
  17. data/lib/grit/git-ruby/object.rb +8 -2
  18. data/lib/grit/git-ruby/repository.rb +11 -6
  19. data/lib/grit/git.rb +23 -10
  20. data/lib/grit/index.rb +12 -11
  21. data/lib/grit/merge.rb +45 -0
  22. data/lib/grit/ref.rb +20 -16
  23. data/lib/grit/repo.rb +59 -9
  24. data/lib/grit/ruby1.9.rb +7 -0
  25. data/lib/grit/submodule.rb +5 -1
  26. data/lib/grit/tag.rb +61 -66
  27. data/lib/grit/tree.rb +20 -1
  28. metadata +29 -47
  29. data/Manifest.txt +0 -71
  30. data/README.txt +0 -213
  31. data/Rakefile +0 -29
  32. data/grit.gemspec +0 -62
  33. data/lib/grit/head.rb +0 -83
  34. data/test/test_actor.rb +0 -35
  35. data/test/test_blob.rb +0 -79
  36. data/test/test_commit.rb +0 -190
  37. data/test/test_config.rb +0 -58
  38. data/test/test_diff.rb +0 -18
  39. data/test/test_git.rb +0 -64
  40. data/test/test_grit.rb +0 -32
  41. data/test/test_head.rb +0 -47
  42. data/test/test_real.rb +0 -19
  43. data/test/test_reality.rb +0 -17
  44. data/test/test_remote.rb +0 -14
  45. data/test/test_repo.rb +0 -277
  46. data/test/test_tag.rb +0 -25
  47. data/test/test_tree.rb +0 -96
@@ -104,14 +104,23 @@ module Grit
104
104
  info = nil
105
105
  end
106
106
  end
107
-
107
+
108
108
  blames
109
109
  end
110
110
 
111
+ def basename
112
+ File.basename(name)
113
+ end
114
+
111
115
  # Pretty object inspection
112
116
  def inspect
113
117
  %Q{#<Grit::Blob "#{@id}">}
114
118
  end
119
+
120
+ # Compares blobs by name
121
+ def <=>(other)
122
+ name <=> other.name
123
+ end
115
124
  end # Blob
116
-
125
+
117
126
  end # Grit
@@ -1,5 +1,5 @@
1
1
  module Grit
2
-
2
+
3
3
  class Commit
4
4
  attr_reader :id
5
5
  lazy_reader :parents
@@ -10,7 +10,8 @@ module Grit
10
10
  lazy_reader :committed_date
11
11
  lazy_reader :message
12
12
  lazy_reader :short_message
13
-
13
+ lazy_reader :author_string
14
+
14
15
  # Instantiate a new Commit
15
16
  # +id+ is the id of the commit
16
17
  # +parents+ is an array of commit ids (will be converted into Commit instances)
@@ -34,11 +35,11 @@ module Grit
34
35
  @message = message.join("\n")
35
36
  @short_message = message[0] || ''
36
37
  end
37
-
38
+
38
39
  def id_abbrev
39
40
  @id_abbrev ||= @repo.git.rev_parse({}, self.id).chomp[0, 7]
40
41
  end
41
-
42
+
42
43
  # Create an unbaked Commit containing just the specified attributes
43
44
  # +repo+ is the Repo
44
45
  # +atts+ is a Hash of instance variable data
@@ -47,7 +48,7 @@ module Grit
47
48
  def self.create(repo, atts)
48
49
  self.allocate.create_initialize(repo, atts)
49
50
  end
50
-
51
+
51
52
  # Initializer for Commit.create
52
53
  # +repo+ is the Repo
53
54
  # +atts+ is a Hash of instance variable data
@@ -60,11 +61,11 @@ module Grit
60
61
  end
61
62
  self
62
63
  end
63
-
64
+
64
65
  def lazy_source
65
66
  self.class.find_all(@repo, @id, {:max_count => 1}).first
66
67
  end
67
-
68
+
68
69
  # Count the number of commits reachable from this ref
69
70
  # +repo+ is the Repo
70
71
  # +ref+ is the ref from which to begin (SHA1 or name)
@@ -73,7 +74,7 @@ module Grit
73
74
  def self.count(repo, ref)
74
75
  repo.git.rev_list({}, ref).size / 41
75
76
  end
76
-
77
+
77
78
  # Find all commits matching the given criteria.
78
79
  # +repo+ is the Repo
79
80
  # +ref+ is the ref from which to begin (SHA1 or name) or nil for --all
@@ -84,21 +85,21 @@ module Grit
84
85
  # Returns Grit::Commit[] (baked)
85
86
  def self.find_all(repo, ref, options = {})
86
87
  allowed_options = [:max_count, :skip, :since]
87
-
88
+
88
89
  default_options = {:pretty => "raw"}
89
90
  actual_options = default_options.merge(options)
90
-
91
+
91
92
  if ref
92
93
  output = repo.git.rev_list(actual_options, ref)
93
94
  else
94
95
  output = repo.git.rev_list(actual_options.merge(:all => true))
95
96
  end
96
-
97
+
97
98
  self.list_from_string(repo, output)
98
99
  rescue Grit::GitRuby::Repository::NoSuchShaFound
99
100
  []
100
101
  end
101
-
102
+
102
103
  # Parse out commit information into an array of baked Commit objects
103
104
  # +repo+ is the Repo
104
105
  # +text+ is the text output from the git command (raw format)
@@ -110,40 +111,40 @@ module Grit
110
111
  #
111
112
  def self.list_from_string(repo, text)
112
113
  lines = text.split("\n")
113
-
114
+
114
115
  commits = []
115
-
116
+
116
117
  while !lines.empty?
117
118
  id = lines.shift.split.last
118
119
  tree = lines.shift.split.last
119
-
120
+
120
121
  parents = []
121
122
  parents << lines.shift.split.last while lines.first =~ /^parent/
122
-
123
+
123
124
  author, authored_date = self.actor(lines.shift)
124
125
  committer, committed_date = self.actor(lines.shift)
125
-
126
+
126
127
  # not doing anything with this yet, but it's sometimes there
127
128
  encoding = lines.shift.split.last if lines.first =~ /^encoding/
128
-
129
+
129
130
  lines.shift
130
-
131
+
131
132
  message_lines = []
132
133
  message_lines << lines.shift[4..-1] while lines.first =~ /^ {4}/
133
-
134
+
134
135
  lines.shift while lines.first && lines.first.empty?
135
-
136
+
136
137
  commits << Commit.new(repo, id, parents, tree, author, authored_date, committer, committed_date, message_lines)
137
138
  end
138
-
139
+
139
140
  commits
140
141
  end
141
-
142
+
142
143
  # Show diffs between two trees:
143
144
  # +repo+ is the Repo
144
145
  # +a+ is a named commit
145
- # +b+ is an optional named commit. Passing an array assumes you
146
- # wish to omit the second named commit and limit the diff to the
146
+ # +b+ is an optional named commit. Passing an array assumes you
147
+ # wish to omit the second named commit and limit the diff to the
147
148
  # given paths.
148
149
  # +paths* is an array of paths to limit the diff.
149
150
  #
@@ -174,10 +175,14 @@ module Grit
174
175
  if parents.empty?
175
176
  show
176
177
  else
177
- self.class.diff(@repo, parents.first.id, @id)
178
+ self.class.diff(@repo, parents.first.id, @id)
178
179
  end
179
180
  end
180
181
 
182
+ def stats
183
+ stats = @repo.commit_stats(self.sha, 1)[0][-1]
184
+ end
185
+
181
186
  # Convert this Commit to a String which is just the SHA1 id
182
187
  def to_s
183
188
  @id
@@ -186,18 +191,22 @@ module Grit
186
191
  def sha
187
192
  @id
188
193
  end
189
-
194
+
190
195
  def date
191
196
  @committed_date
192
197
  end
193
-
198
+
199
+ def to_patch
200
+ @repo.git.format_patch({'1' => true, :stdout => true}, to_s)
201
+ end
202
+
194
203
  # Pretty object inspection
195
204
  def inspect
196
205
  %Q{#<Grit::Commit "#{@id}">}
197
206
  end
198
-
207
+
199
208
  # private
200
-
209
+
201
210
  # Parse out the actor (author or committer) info
202
211
  #
203
212
  # Returns [String (actor name and email), Time (acted at time)]
@@ -206,6 +215,10 @@ module Grit
206
215
  [Actor.from_string(actor), Time.at(epoch.to_i)]
207
216
  end
208
217
 
218
+ def author_string
219
+ "%s <%s> %s %+05d" % [author.name, author.email, authored_date.to_i, 800]
220
+ end
221
+
209
222
  def to_hash
210
223
  {
211
224
  'id' => id,
@@ -225,5 +238,5 @@ module Grit
225
238
  }
226
239
  end
227
240
  end # Commit
228
-
241
+
229
242
  end # Grit
@@ -62,12 +62,12 @@ module Grit
62
62
  lines.shift
63
63
 
64
64
  message_lines = []
65
- message_lines << lines.shift[4..-1] while lines.first =~ /^ {4}/
65
+ message_lines << lines.shift[4..-1] while lines.first =~ /^ {4}/ || lines.first == ''
66
66
 
67
67
  lines.shift while lines.first && lines.first.empty?
68
68
 
69
69
  files = []
70
- while lines.first =~ /^(\d+)\s+(\d+)\s+(.+)/
70
+ while lines.first =~ /^([-\d]+)\s+([-\d]+)\s+(.+)/
71
71
  (additions, deletions, filename) = lines.shift.split
72
72
  additions = additions.to_i
73
73
  deletions = deletions.to_i
@@ -88,6 +88,13 @@ module Grit
88
88
  %Q{#<Grit::CommitStats "#{@id}">}
89
89
  end
90
90
 
91
+ # Convert to an easy-to-traverse structure
92
+ def to_diffstat
93
+ files.map do |metadata|
94
+ DiffStat.new(*metadata)
95
+ end
96
+ end
97
+
91
98
  # private
92
99
 
93
100
  def to_hash
@@ -99,6 +106,23 @@ module Grit
99
106
  'total' => total
100
107
  }
101
108
  end
109
+
102
110
  end # CommitStats
103
111
 
112
+ class DiffStat
113
+ attr_reader :filename, :additions, :deletions
114
+
115
+ def initialize(filename, additions, deletions, total=nil)
116
+ @filename, @additions, @deletions = filename, additions, deletions
117
+ end
118
+
119
+ def net
120
+ additions - deletions
121
+ end
122
+
123
+ def inspect
124
+ "#{filename}: +#{additions} -#{deletions}"
125
+ end
126
+ end
127
+
104
128
  end # Grit
@@ -2,17 +2,17 @@ module Grit
2
2
 
3
3
  class Diff
4
4
  attr_reader :a_path, :b_path
5
- attr_reader :a_commit, :b_commit
5
+ attr_reader :a_blob, :b_blob
6
6
  attr_reader :a_mode, :b_mode
7
7
  attr_reader :new_file, :deleted_file
8
8
  attr_reader :diff
9
9
 
10
- def initialize(repo, a_path, b_path, a_commit, b_commit, a_mode, b_mode, new_file, deleted_file, diff)
10
+ def initialize(repo, a_path, b_path, a_blob, b_blob, a_mode, b_mode, new_file, deleted_file, diff)
11
11
  @repo = repo
12
12
  @a_path = a_path
13
13
  @b_path = b_path
14
- @a_commit = a_commit =~ /^0{40}$/ ? nil : Commit.create(repo, :id => a_commit)
15
- @b_commit = b_commit =~ /^0{40}$/ ? nil : Commit.create(repo, :id => b_commit)
14
+ @a_blob = a_blob =~ /^0{40}$/ ? nil : Blob.create(repo, :id => a_blob)
15
+ @b_blob = b_blob =~ /^0{40}$/ ? nil : Blob.create(repo, :id => b_blob)
16
16
  @a_mode = a_mode
17
17
  @b_mode = b_mode
18
18
  @new_file = new_file
@@ -51,7 +51,7 @@ module Grit
51
51
  deleted_file = true
52
52
  end
53
53
 
54
- m, a_commit, b_commit, b_mode = *lines.shift.match(%r{^index ([0-9A-Fa-f]+)\.\.([0-9A-Fa-f]+) ?(.+)?$})
54
+ m, a_blob, b_blob, b_mode = *lines.shift.match(%r{^index ([0-9A-Fa-f]+)\.\.([0-9A-Fa-f]+) ?(.+)?$})
55
55
  b_mode.strip! if b_mode
56
56
 
57
57
  diff_lines = []
@@ -60,7 +60,7 @@ module Grit
60
60
  end
61
61
  diff = diff_lines.join("\n")
62
62
 
63
- diffs << Diff.new(repo, a_path, b_path, a_commit, b_commit, a_mode, b_mode, new_file, deleted_file, diff)
63
+ diffs << Diff.new(repo, a_path, b_path, a_blob, b_blob, a_mode, b_mode, new_file, deleted_file, diff)
64
64
  end
65
65
 
66
66
  diffs
@@ -72,8 +72,8 @@ module Grit
72
72
  (sha1, sha2) = string.split('..')
73
73
  return [rev_parse({}, sha1), rev_parse({}, sha2)]
74
74
  end
75
-
76
- if /\w{40}/.match(string) # passing in a sha - just no-op it
75
+
76
+ if /^[0-9a-f]{40}$/.match(string) # passing in a sha - just no-op it
77
77
  return string.chomp
78
78
  end
79
79
 
@@ -113,6 +113,8 @@ module Grit
113
113
 
114
114
  def blame_tree(commit, path = nil)
115
115
  begin
116
+ path = [path].join('/').to_s + '/' if (path && path != '')
117
+ path = '' if !path.is_a? String
116
118
  commits = file_index.last_commits(rev_parse({}, commit), looking_for(commit, path))
117
119
  clean_paths(commits)
118
120
  rescue FileIndex::IndexFileNotFound
@@ -22,12 +22,18 @@ module Grit
22
22
  class UnsupportedRef < StandardError
23
23
  end
24
24
 
25
+ class << self
26
+ attr_accessor :max_file_size
27
+ end
28
+
29
+ self.max_file_size = 10_000_000 # ~10M
30
+
25
31
  attr_reader :files
26
32
 
27
33
  # initializes index given repo_path
28
34
  def initialize(repo_path)
29
35
  @index_file = File.join(repo_path, 'file-index')
30
- if File.file?(@index_file)
36
+ if File.file?(@index_file) && (File.size(@index_file) < Grit::GitRuby::FileIndex.max_file_size)
31
37
  read_index
32
38
  else
33
39
  raise IndexFileNotFound
@@ -46,6 +52,7 @@ module Grit
46
52
  commits_from(commit_sha).size
47
53
  end
48
54
 
55
+ # builds a list of all commits reachable from a single commit
49
56
  def commits_from(commit_sha)
50
57
  raise UnsupportedRef if commit_sha.is_a? Array
51
58
 
@@ -69,7 +76,7 @@ module Grit
69
76
  end
70
77
 
71
78
  def sort_commits(sha_array)
72
- sha_array.sort { |a, b| @commit_order[b] <=> @commit_order[a] }
79
+ sha_array.sort { |a, b| @commit_order[b].to_i <=> @commit_order[a].to_i }
73
80
  end
74
81
 
75
82
  # returns files changed at commit sha
@@ -183,4 +190,4 @@ if __FILE__ == $0
183
190
  end
184
191
 
185
192
 
186
-
193
+
@@ -115,7 +115,7 @@ module Grit
115
115
  def initialize(mode, filename, sha1o)
116
116
  @mode = 0
117
117
  mode.each_byte do |i|
118
- @mode = (@mode << 3) | (i-'0'[0])
118
+ @mode = (@mode << 3) | (i-'0'.getord(0))
119
119
  end
120
120
  @name = filename
121
121
  @sha1 = sha1o
@@ -179,8 +179,14 @@ module Grit
179
179
 
180
180
  def self.read_bytes_until(io, char)
181
181
  string = ''
182
- while ((next_char = io.getc.chr) != char) && !io.eof
183
- string += next_char
182
+ if RUBY_VERSION > '1.9'
183
+ while ((next_char = io.getc) != char) && !io.eof
184
+ string += next_char
185
+ end
186
+ else
187
+ while ((next_char = io.getc.chr) != char) && !io.eof
188
+ string += next_char
189
+ end
184
190
  end
185
191
  string
186
192
  end
@@ -12,7 +12,7 @@
12
12
  module Grit
13
13
  module GitRuby
14
14
  module Internal
15
- class Mmap
15
+ class FileWindow
16
16
  def initialize(file, version = 1)
17
17
  @file = file
18
18
  @offset = nil
@@ -46,7 +46,7 @@ module Grit
46
46
  end
47
47
  @offset = offset + len ? len : 1
48
48
  if not len
49
- @file.read(1)[0]
49
+ @file.read(1).getord(0)
50
50
  else
51
51
  @file.read(len)
52
52
  end
@@ -29,7 +29,7 @@ module Grit
29
29
  begin
30
30
  return nil unless sha1[0...2] && sha1[2..39]
31
31
  path = @directory + '/' + sha1[0...2] + '/' + sha1[2..39]
32
- get_raw_object(File.read(path))
32
+ get_raw_object(File.open(path, 'rb').read)
33
33
  rescue Errno::ENOENT
34
34
  nil
35
35
  end
@@ -76,7 +76,7 @@ module Grit
76
76
  content = Zlib::Deflate.deflate(store)
77
77
 
78
78
  FileUtils.mkdir_p(@directory+'/'+sha1[0...2])
79
- File.open(path, 'w') do |f|
79
+ File.open(path, 'wb') do |f|
80
80
  f.write content
81
81
  end
82
82
  end
@@ -102,7 +102,7 @@ module Grit
102
102
  # private
103
103
  def unpack_object_header_gently(buf)
104
104
  used = 0
105
- c = buf[used]
105
+ c = buf.getord(used)
106
106
  used += 1
107
107
 
108
108
  type = (c >> 4) & 7;
@@ -112,7 +112,7 @@ module Grit
112
112
  if buf.length <= used
113
113
  raise LooseObjectError, "object file too short"
114
114
  end
115
- c = buf[used]
115
+ c = buf.getord(used)
116
116
  used += 1
117
117
 
118
118
  size += (c & 0x7f) << shift
@@ -127,8 +127,8 @@ module Grit
127
127
  private :unpack_object_header_gently
128
128
 
129
129
  def legacy_loose_object?(buf)
130
- word = (buf[0] << 8) + buf[1]
131
- buf[0] == 0x78 && word % 31 == 0
130
+ word = (buf.getord(0) << 8) + buf.getord(1)
131
+ buf.getord(0) == 0x78 && word % 31 == 0
132
132
  end
133
133
  private :legacy_loose_object?
134
134
  end