grit 1.0.1 → 1.1.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/History.txt +32 -2
- data/README.md +210 -0
- data/VERSION.yml +2 -2
- data/lib/grit.rb +11 -4
- data/lib/grit/blob.rb +11 -2
- data/lib/grit/commit.rb +41 -33
- data/lib/grit/commit_stats.rb +26 -2
- data/lib/grit/diff.rb +6 -6
- data/lib/grit/git-ruby.rb +1 -1
- data/lib/grit/git-ruby/git_object.rb +9 -3
- data/lib/grit/git-ruby/internal/{mmap.rb → file_window.rb} +2 -2
- data/lib/grit/git-ruby/internal/loose.rb +6 -6
- data/lib/grit/git-ruby/internal/pack.rb +19 -19
- data/lib/grit/git-ruby/object.rb +8 -2
- data/lib/grit/git-ruby/repository.rb +5 -6
- data/lib/grit/git.rb +14 -8
- data/lib/grit/index.rb +2 -2
- data/lib/grit/ref.rb +4 -6
- data/lib/grit/repo.rb +25 -3
- data/lib/grit/ruby1.9.rb +7 -0
- data/lib/grit/submodule.rb +5 -1
- data/lib/grit/tag.rb +61 -66
- data/lib/grit/tree.rb +20 -1
- data/test/dot_git/objects/b7/f932bd02b3e0a4228ee7b55832749028d345de +1 -0
- data/test/dot_git/packed-refs +2 -1
- data/test/dot_git/refs/tags/annotated +1 -0
- data/test/dot_git/refs/tags/not_annotated +1 -0
- data/test/fixtures/rev_list_delta_a +8 -0
- data/test/fixtures/rev_list_delta_b +11 -0
- data/test/fixtures/show_cc +637 -0
- data/test/helper.rb +1 -0
- data/test/test_blob.rb +18 -14
- data/test/test_commit.rb +65 -48
- data/test/test_git.rb +21 -1
- data/test/test_repo.rb +26 -0
- data/test/test_rubygit.rb +7 -2
- data/test/test_submodule.rb +18 -0
- data/test/test_tag.rb +53 -11
- data/test/test_tree.rb +5 -0
- metadata +11 -4
- data/README.txt +0 -222
data/lib/grit/commit_stats.rb
CHANGED
@@ -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 =~ /^(
|
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
|
data/lib/grit/diff.rb
CHANGED
@@ -2,17 +2,17 @@ module Grit
|
|
2
2
|
|
3
3
|
class Diff
|
4
4
|
attr_reader :a_path, :b_path
|
5
|
-
attr_reader :
|
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,
|
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
|
-
@
|
15
|
-
@
|
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,
|
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,
|
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
|
data/lib/grit/git-ruby.rb
CHANGED
@@ -113,7 +113,7 @@ module Grit
|
|
113
113
|
|
114
114
|
def blame_tree(commit, path = nil)
|
115
115
|
begin
|
116
|
-
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'
|
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
|
-
|
183
|
-
|
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
|
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)
|
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.
|
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, '
|
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
|
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
|
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
|
131
|
-
buf
|
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/
|
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 =
|
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
|
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)
|
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)
|
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
|
284
|
+
c = data.getord(i)
|
285
285
|
base_offset = c & 0x7f
|
286
286
|
while c & 0x80 != 0
|
287
|
-
c = data
|
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
|
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
|
344
|
-
cp_off |= delta
|
345
|
-
cp_off |= delta
|
346
|
-
cp_off |= delta
|
347
|
-
cp_size = delta
|
348
|
-
cp_size |= delta
|
349
|
-
cp_size |= delta
|
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
|
368
|
+
c = delta.getord(pos)
|
369
369
|
if c == nil
|
370
370
|
raise PackFormatError, 'invalid delta header'
|
371
371
|
end
|
data/lib/grit/git-ruby/object.rb
CHANGED
@@ -163,8 +163,14 @@ module Grit
|
|
163
163
|
|
164
164
|
def self.read_bytes_until(io, char)
|
165
165
|
string = ''
|
166
|
-
|
167
|
-
|
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
|
-
|
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
|
-
|
192
|
-
|
193
|
-
|
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)
|
data/lib/grit/git.rb
CHANGED
@@ -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
|
22
|
-
self.git_timeout
|
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) >
|
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
|
data/lib/grit/index.rb
CHANGED
@@ -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*")
|
data/lib/grit/ref.rb
CHANGED
@@ -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
|