grit 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -113,7 +113,7 @@ module Grit
113
113
 
114
114
  def blame_tree(commit, path = nil)
115
115
  begin
116
- path = path.to_a.join('/').to_s + '/' if (path && path != '')
116
+ path = [path].join('/').to_s + '/' if (path && path != '')
117
117
  path = '' if !path.is_a? String
118
118
  commits = file_index.last_commits(rev_parse({}, commit), looking_for(commit, path))
119
119
  clean_paths(commits)
@@ -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
@@ -11,7 +11,7 @@
11
11
 
12
12
  require 'zlib'
13
13
  require 'grit/git-ruby/internal/raw_object'
14
- require 'grit/git-ruby/internal/mmap'
14
+ require 'grit/git-ruby/internal/file_window'
15
15
 
16
16
  PACK_SIGNATURE = "PACK"
17
17
  PACK_IDX_SIGNATURE = "\377tOc"
@@ -48,9 +48,9 @@ module Grit
48
48
  def with_idx(index_file = nil)
49
49
  if !index_file
50
50
  index_file = @name
51
- idxfile = File.open(@name[0...-4]+'idx')
51
+ idxfile = File.open(@name[0...-4]+'idx', 'rb')
52
52
  else
53
- idxfile = File.open(index_file)
53
+ idxfile = File.open(index_file, 'rb')
54
54
  end
55
55
 
56
56
  # read header
@@ -66,14 +66,14 @@ module Grit
66
66
  @version = 1
67
67
  end
68
68
 
69
- idx = Mmap.new(idxfile, @version)
69
+ idx = FileWindow.new(idxfile, @version)
70
70
  yield idx
71
71
  idx.unmap
72
72
  idxfile.close
73
73
  end
74
74
 
75
75
  def with_packfile
76
- packfile = File.open(@name)
76
+ packfile = File.open(@name, 'rb')
77
77
  yield packfile
78
78
  packfile.close
79
79
  end
@@ -189,7 +189,7 @@ module Grit
189
189
  end
190
190
 
191
191
  def find_object_in_index(idx, sha1)
192
- slot = sha1[0]
192
+ slot = sha1.getord(0)
193
193
  return nil if !slot
194
194
  first, last = @offsets[slot,2]
195
195
  while first < last
@@ -248,13 +248,13 @@ module Grit
248
248
  obj_offset = offset
249
249
  packfile.seek(offset)
250
250
 
251
- c = packfile.read(1)[0]
251
+ c = packfile.read(1).getord(0)
252
252
  size = c & 0xf
253
253
  type = (c >> 4) & 7
254
254
  shift = 4
255
255
  offset += 1
256
256
  while c & 0x80 != 0
257
- c = packfile.read(1)[0]
257
+ c = packfile.read(1).getord(0)
258
258
  size |= ((c & 0x7f) << shift)
259
259
  shift += 7
260
260
  offset += 1
@@ -281,10 +281,10 @@ module Grit
281
281
 
282
282
  if type == OBJ_OFS_DELTA
283
283
  i = 0
284
- c = data[i]
284
+ c = data.getord(i)
285
285
  base_offset = c & 0x7f
286
286
  while c & 0x80 != 0
287
- c = data[i += 1]
287
+ c = data.getord(i += 1)
288
288
  base_offset += 1
289
289
  base_offset <<= 7
290
290
  base_offset |= c & 0x7f
@@ -335,18 +335,18 @@ module Grit
335
335
  dest_size, pos = patch_delta_header_size(delta, pos)
336
336
  dest = ""
337
337
  while pos < delta.size
338
- c = delta[pos]
338
+ c = delta.getord(pos)
339
339
  pos += 1
340
340
  if c & 0x80 != 0
341
341
  pos -= 1
342
342
  cp_off = cp_size = 0
343
- cp_off = delta[pos += 1] if c & 0x01 != 0
344
- cp_off |= delta[pos += 1] << 8 if c & 0x02 != 0
345
- cp_off |= delta[pos += 1] << 16 if c & 0x04 != 0
346
- cp_off |= delta[pos += 1] << 24 if c & 0x08 != 0
347
- cp_size = delta[pos += 1] if c & 0x10 != 0
348
- cp_size |= delta[pos += 1] << 8 if c & 0x20 != 0
349
- cp_size |= delta[pos += 1] << 16 if c & 0x40 != 0
343
+ cp_off = delta.getord(pos += 1) if c & 0x01 != 0
344
+ cp_off |= delta.getord(pos += 1) << 8 if c & 0x02 != 0
345
+ cp_off |= delta.getord(pos += 1) << 16 if c & 0x04 != 0
346
+ cp_off |= delta.getord(pos += 1) << 24 if c & 0x08 != 0
347
+ cp_size = delta.getord(pos += 1) if c & 0x10 != 0
348
+ cp_size |= delta.getord(pos += 1) << 8 if c & 0x20 != 0
349
+ cp_size |= delta.getord(pos += 1) << 16 if c & 0x40 != 0
350
350
  cp_size = 0x10000 if cp_size == 0
351
351
  pos += 1
352
352
  dest += base[cp_off,cp_size]
@@ -365,7 +365,7 @@ module Grit
365
365
  size = 0
366
366
  shift = 0
367
367
  begin
368
- c = delta[pos]
368
+ c = delta.getord(pos)
369
369
  if c == nil
370
370
  raise PackFormatError, 'invalid delta header'
371
371
  end
@@ -163,8 +163,14 @@ module Grit
163
163
 
164
164
  def self.read_bytes_until(io, char)
165
165
  string = ''
166
- while ((next_char = io.getc.chr) != char) && !io.eof
167
- string += next_char
166
+ if RUBY_VERSION > '1.9'
167
+ while ((next_char = io.getc) != char) && !io.eof
168
+ string += next_char
169
+ end
170
+ else
171
+ while ((next_char = io.getc.chr) != char) && !io.eof
172
+ string += next_char
173
+ end
168
174
  end
169
175
  string
170
176
  end
@@ -185,16 +185,15 @@ module Grit
185
185
  def get_raw_tree(sha)
186
186
  o = get_raw_object_by_sha1(sha)
187
187
  if o.type == :commit
188
- tree = cat_file(get_object_by_sha1(sha).tree)
188
+ cat_file(get_object_by_sha1(sha).tree)
189
189
  elsif o.type == :tag
190
190
  commit_sha = get_object_by_sha1(sha).object
191
- tree = cat_file(get_object_by_sha1(commit_sha).tree)
192
- else
193
- tree = cat_file(sha)
191
+ cat_file(get_object_by_sha1(commit_sha).tree)
192
+ elsif o.type == :tree
193
+ cat_file(sha)
194
194
  end
195
- return tree
196
195
  end
197
-
196
+
198
197
  # return array of tree entries
199
198
  ## TODO : refactor this to remove the fugly
200
199
  def ls_tree_path(sha, path, append = nil)
@@ -15,11 +15,12 @@ module Grit
15
15
  include GitRuby
16
16
 
17
17
  class << self
18
- attr_accessor :git_binary, :git_timeout
18
+ attr_accessor :git_binary, :git_timeout, :git_max_size
19
19
  end
20
20
 
21
- self.git_binary = "/usr/bin/env git"
22
- self.git_timeout = 10
21
+ self.git_binary = "/usr/bin/env git"
22
+ self.git_timeout = 10
23
+ self.git_max_size = 5242880 # 5.megabytes
23
24
 
24
25
  def self.with_timeout(timeout = 10.seconds)
25
26
  old_timeout = Grit::Git.git_timeout
@@ -35,6 +36,11 @@ module Grit
35
36
  self.bytes_read = 0
36
37
  end
37
38
 
39
+ def shell_escape(str)
40
+ str.to_s.gsub("'", "\\\\'").gsub(";", '\\;')
41
+ end
42
+ alias_method :e, :shell_escape
43
+
38
44
  # Run the given git command with the specified arguments and return
39
45
  # the result as a String
40
46
  # +cmd+ is the command
@@ -54,9 +60,9 @@ module Grit
54
60
  timeout = true if timeout.nil?
55
61
 
56
62
  opt_args = transform_options(options)
57
- ext_args = args.reject { |a| a.empty? }.map { |a| (a == '--' || a[0].chr == '|') ? a : "'#{a}'" }
63
+ ext_args = args.reject { |a| a.empty? }.map { |a| (a == '--' || a[0].chr == '|') ? a : "'#{e(a)}'" }
58
64
 
59
- call = "#{prefix}#{Git.git_binary} --git-dir='#{self.git_dir}' #{cmd.to_s.gsub(/_/, '-')} #{(opt_args + ext_args).join(' ')}#{postfix}"
65
+ call = "#{prefix}#{Git.git_binary} --git-dir='#{self.git_dir}' #{cmd.to_s.gsub(/_/, '-')} #{(opt_args + ext_args).join(' ')}#{e(postfix)}"
60
66
  Grit.log(call) if Grit.debug
61
67
  response, err = timeout ? sh(call) : wild_sh(call)
62
68
  Grit.log(response) if Grit.debug
@@ -70,7 +76,7 @@ module Grit
70
76
  Timeout.timeout(self.class.git_timeout) do
71
77
  while tmp = stdout.read(1024)
72
78
  ret += tmp
73
- if (@bytes_read += tmp.size) > 5242880 # 5.megabytes
79
+ if (@bytes_read += tmp.size) > self.class.git_max_size
74
80
  bytes = @bytes_read
75
81
  @bytes_read = 0
76
82
  raise GitTimeout.new(command, bytes)
@@ -116,14 +122,14 @@ module Grit
116
122
  args << "-#{opt}"
117
123
  else
118
124
  val = options.delete(opt)
119
- args << "-#{opt.to_s} '#{val}'"
125
+ args << "-#{opt.to_s} '#{e(val)}'"
120
126
  end
121
127
  else
122
128
  if options[opt] == true
123
129
  args << "--#{opt.to_s.gsub(/_/, '-')}"
124
130
  else
125
131
  val = options.delete(opt)
126
- args << "--#{opt.to_s.gsub(/_/, '-')}='#{val}'"
132
+ args << "--#{opt.to_s.gsub(/_/, '-')}='#{e(val)}'"
127
133
  end
128
134
  end
129
135
  end
@@ -93,12 +93,12 @@ module Grit
93
93
  # overwrite with new tree contents
94
94
  tree.each do |k, v|
95
95
  case v
96
- when String:
96
+ when String
97
97
  sha = write_blob(v)
98
98
  sha = [sha].pack("H*")
99
99
  str = "%s %s\0%s" % ['100644', k, sha]
100
100
  tree_contents[k] = str
101
- when Hash:
101
+ when Hash
102
102
  ctree = now_tree/k if now_tree
103
103
  sha = write_tree(v, ctree)
104
104
  sha = [sha].pack("H*")
@@ -9,7 +9,7 @@ module Grit
9
9
  # +options+ is a Hash of options
10
10
  #
11
11
  # Returns Grit::Ref[] (baked)
12
- def find_all(repo, options = {})
12
+ def find_all(repo, options = {})
13
13
  refs = []
14
14
  already = {}
15
15
  Dir.chdir(repo.path) do
@@ -37,9 +37,9 @@ module Grit
37
37
  end
38
38
  end
39
39
  end
40
- end
40
+ end
41
41
  end
42
-
42
+
43
43
  refs
44
44
  end
45
45
 
@@ -94,8 +94,6 @@ module Grit
94
94
 
95
95
  end # Head
96
96
 
97
- class Tag < Ref ; end
98
-
99
97
  class Remote < Ref; end
100
-
98
+
101
99
  end # Grit