gitrb 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/gitrb.gemspec +1 -1
- data/lib/gitrb/commit.rb +5 -5
- data/lib/gitrb/pack.rb +14 -14
- data/lib/gitrb/repository.rb +53 -32
- data/lib/gitrb/tag.rb +3 -2
- data/lib/gitrb/tree.rb +5 -5
- data/lib/gitrb/util.rb +0 -4
- data/test/repository_spec.rb +33 -2
- metadata +2 -2
data/gitrb.gemspec
CHANGED
data/lib/gitrb/commit.rb
CHANGED
@@ -47,20 +47,20 @@ module Gitrb
|
|
47
47
|
|
48
48
|
def parse(data)
|
49
49
|
headers, @message = data.split("\n\n", 2)
|
50
|
-
repository.
|
50
|
+
repository.set_encoding(@message)
|
51
51
|
|
52
52
|
headers.split("\n").each do |header|
|
53
53
|
key, value = header.split(' ', 2)
|
54
54
|
|
55
55
|
case key
|
56
56
|
when 'parent'
|
57
|
-
@parent << Reference.new(:repository => repository, :id => repository.
|
57
|
+
@parent << Reference.new(:repository => repository, :id => repository.set_encoding(value))
|
58
58
|
when 'author'
|
59
|
-
@author = User.parse(repository.
|
59
|
+
@author = User.parse(repository.set_encoding(value))
|
60
60
|
when 'committer'
|
61
|
-
@committer = User.parse(repository.
|
61
|
+
@committer = User.parse(repository.set_encoding(value))
|
62
62
|
when 'tree'
|
63
|
-
@tree = Reference.new(:repository => repository, :id => repository.
|
63
|
+
@tree = Reference.new(:repository => repository, :id => repository.set_encoding(value))
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
data/lib/gitrb/pack.rb
CHANGED
@@ -159,7 +159,7 @@ module Gitrb
|
|
159
159
|
|
160
160
|
def find_object(sha1)
|
161
161
|
with_idx do |idx|
|
162
|
-
slot =
|
162
|
+
slot = sha1[0].ord
|
163
163
|
return nil if !slot
|
164
164
|
first, last = @offsets[slot,2]
|
165
165
|
while first < last
|
@@ -200,13 +200,13 @@ module Gitrb
|
|
200
200
|
obj_offset = offset
|
201
201
|
packfile.seek(offset)
|
202
202
|
|
203
|
-
c =
|
203
|
+
c = packfile.read(1)[0].ord
|
204
204
|
size = c & 0xf
|
205
205
|
type = (c >> 4) & 7
|
206
206
|
shift = 4
|
207
207
|
offset += 1
|
208
208
|
while c & 0x80 != 0
|
209
|
-
c =
|
209
|
+
c = packfile.read(1)[0].ord
|
210
210
|
size |= ((c & 0x7f) << shift)
|
211
211
|
shift += 7
|
212
212
|
offset += 1
|
@@ -229,10 +229,10 @@ module Gitrb
|
|
229
229
|
|
230
230
|
if type == OBJ_OFS_DELTA
|
231
231
|
i = 0
|
232
|
-
c =
|
232
|
+
c = data[i].ord
|
233
233
|
base_offset = c & 0x7f
|
234
234
|
while c & 0x80 != 0
|
235
|
-
c =
|
235
|
+
c = data[i += 1].ord
|
236
236
|
base_offset += 1
|
237
237
|
base_offset <<= 7
|
238
238
|
base_offset |= c & 0x7f
|
@@ -279,18 +279,18 @@ module Gitrb
|
|
279
279
|
dest_size, pos = patch_delta_header_size(delta, pos)
|
280
280
|
dest = ""
|
281
281
|
while pos < delta.size
|
282
|
-
c =
|
282
|
+
c = delta[pos].ord
|
283
283
|
pos += 1
|
284
284
|
if c & 0x80 != 0
|
285
285
|
pos -= 1
|
286
286
|
cp_off = cp_size = 0
|
287
|
-
cp_off =
|
288
|
-
cp_off |=
|
289
|
-
cp_off |=
|
290
|
-
cp_off |=
|
291
|
-
cp_size =
|
292
|
-
cp_size |=
|
293
|
-
cp_size |=
|
287
|
+
cp_off = delta[pos += 1].ord if c & 0x01 != 0
|
288
|
+
cp_off |= delta[pos += 1].ord << 8 if c & 0x02 != 0
|
289
|
+
cp_off |= delta[pos += 1].ord << 16 if c & 0x04 != 0
|
290
|
+
cp_off |= delta[pos += 1].ord << 24 if c & 0x08 != 0
|
291
|
+
cp_size = delta[pos += 1].ord if c & 0x10 != 0
|
292
|
+
cp_size |= delta[pos += 1].ord << 8 if c & 0x20 != 0
|
293
|
+
cp_size |= delta[pos += 1].ord << 16 if c & 0x40 != 0
|
294
294
|
cp_size = 0x10000 if cp_size == 0
|
295
295
|
pos += 1
|
296
296
|
dest << base[cp_off,cp_size]
|
@@ -308,7 +308,7 @@ module Gitrb
|
|
308
308
|
size = 0
|
309
309
|
shift = 0
|
310
310
|
begin
|
311
|
-
c =
|
311
|
+
c = delta[pos].ord
|
312
312
|
if c == nil
|
313
313
|
raise PackFormatError, 'invalid delta header'
|
314
314
|
end
|
data/lib/gitrb/repository.rb
CHANGED
@@ -22,12 +22,24 @@ module Gitrb
|
|
22
22
|
class Repository
|
23
23
|
attr_reader :path, :index, :root, :branch, :lock_file, :head, :encoding
|
24
24
|
|
25
|
+
SHA_PATTERN = /[A-Fa-f0-9]{5,40}/
|
26
|
+
REVISION_PATTERN = /[\w\-\.]+([\^~](\d+)?)*/
|
27
|
+
|
28
|
+
# Encoding stuff
|
29
|
+
DEFAULT_ENCODING = 'utf-8'
|
30
|
+
|
31
|
+
if RUBY_VERSION > '1.9'
|
32
|
+
def set_encoding(s); s.force_encoding(@encoding); end
|
33
|
+
else
|
34
|
+
def set_encoding(s); s; end
|
35
|
+
end
|
36
|
+
|
25
37
|
# Initialize a repository.
|
26
38
|
def initialize(options = {})
|
27
39
|
@bare = options[:bare] || false
|
28
40
|
@branch = options[:branch] || 'master'
|
29
41
|
@logger = options[:logger] || Logger.new(nil)
|
30
|
-
@encoding = options[:encoding] ||
|
42
|
+
@encoding = options[:encoding] || DEFAULT_ENCODING
|
31
43
|
|
32
44
|
@path = options[:path]
|
33
45
|
@path.chomp!('/')
|
@@ -49,18 +61,6 @@ module Gitrb
|
|
49
61
|
load
|
50
62
|
end
|
51
63
|
|
52
|
-
# Encode string
|
53
|
-
if RUBY_VERSION > '1.9'
|
54
|
-
def encode(s)
|
55
|
-
# We have binary data which has to be encoded
|
56
|
-
s.force_encoding(@encoding)
|
57
|
-
end
|
58
|
-
else
|
59
|
-
def encode(s)
|
60
|
-
s
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
64
|
# Bare repository?
|
65
65
|
def bare?
|
66
66
|
@bare
|
@@ -89,9 +89,15 @@ module Gitrb
|
|
89
89
|
|
90
90
|
# Diff
|
91
91
|
def diff(from, to, path = nil)
|
92
|
-
|
93
|
-
|
94
|
-
|
92
|
+
if from && !(Commit === from)
|
93
|
+
raise ArgumentError if !(String === from)
|
94
|
+
from = Reference.new(:repository => self, :id => from)
|
95
|
+
end
|
96
|
+
if !(Commit === to)
|
97
|
+
raise ArgumentError if !(String === to)
|
98
|
+
to = Reference.new(:repository => self, :id => to)
|
99
|
+
end
|
100
|
+
Diff.new(from, to, git_diff_tree('--root', '-u', '--full-index', from && from.id, to.id, '--', path))
|
95
101
|
end
|
96
102
|
|
97
103
|
# All changes made inside a transaction are atomic. If some
|
@@ -155,7 +161,7 @@ module Gitrb
|
|
155
161
|
end
|
156
162
|
commits
|
157
163
|
rescue => ex
|
158
|
-
return [] if ex.message =~ /bad default revision 'HEAD'/
|
164
|
+
return [] if ex.message =~ /bad default revision 'HEAD'/i
|
159
165
|
raise
|
160
166
|
end
|
161
167
|
|
@@ -163,20 +169,29 @@ module Gitrb
|
|
163
169
|
#
|
164
170
|
# Returns a tree, blob, commit or tag object.
|
165
171
|
def get(id)
|
166
|
-
|
167
|
-
|
168
|
-
|
172
|
+
raise NotFound, "No id given" if id.nil?
|
173
|
+
if id =~ SHA_PATTERN
|
174
|
+
raise NotFound, "Sha too short" if id.length < 5
|
175
|
+
list = @objects.find(id).to_a
|
176
|
+
return list.first if list.size == 1
|
177
|
+
elsif id =~ REVISION_PATTERN
|
178
|
+
list = git_rev_parse(id).split("\n") rescue nil
|
179
|
+
raise NotFound, "Revision not found" if !list || list.empty?
|
180
|
+
raise NotFound, "Revision is ambiguous" if list.size > 1
|
181
|
+
id = list.first
|
182
|
+
end
|
169
183
|
|
170
184
|
@logger.debug "gitrb: Loading #{id}"
|
171
185
|
|
172
186
|
path = object_path(id)
|
173
187
|
if File.exists?(path) || (glob = Dir.glob(path + '*')).size >= 1
|
174
188
|
if glob
|
175
|
-
raise NotFound, "Sha
|
176
|
-
path = glob
|
189
|
+
raise NotFound, "Sha is ambiguous" if glob.size > 1
|
190
|
+
path = glob.first
|
191
|
+
id = path[-41..-40] + path[-38..-1]
|
177
192
|
end
|
178
193
|
|
179
|
-
buf = File.open(path,
|
194
|
+
buf = File.open(path, 'rb') { |f| f.read }
|
180
195
|
|
181
196
|
raise NotFound, "Not a loose object: #{id}" if !legacy_loose_object?(buf)
|
182
197
|
|
@@ -185,18 +200,22 @@ module Gitrb
|
|
185
200
|
|
186
201
|
raise NotFound, "Bad object: #{id}" if content.length != size.to_i
|
187
202
|
else
|
188
|
-
|
189
|
-
|
203
|
+
trie = @packs.find(id)
|
204
|
+
raise NotFound, "Object not found" if !trie
|
205
|
+
|
206
|
+
id += trie.key[-(41 - id.length)...-1]
|
207
|
+
|
208
|
+
list = trie.to_a
|
209
|
+
raise NotFound, "Sha is ambiguous" if list.size > 1
|
190
210
|
|
191
211
|
pack, offset = list.first
|
192
212
|
content, type = pack.get_object(offset)
|
193
213
|
end
|
194
214
|
|
195
|
-
raise NotFound, "Object not found" if !type
|
196
|
-
|
197
215
|
@logger.debug "gitrb: Loaded #{id}"
|
198
216
|
|
199
|
-
|
217
|
+
set_encoding(id)
|
218
|
+
object = Gitrb::Object.factory(type, :repository => self, :id => id, :data => content)
|
200
219
|
@objects.insert(id, object)
|
201
220
|
object
|
202
221
|
end
|
@@ -225,6 +244,7 @@ module Gitrb
|
|
225
244
|
|
226
245
|
@logger.debug "gitrb: Stored #{id}"
|
227
246
|
|
247
|
+
set_encoding(id)
|
228
248
|
object.repository = self
|
229
249
|
object.id = id
|
230
250
|
@objects.insert(id, object)
|
@@ -242,10 +262,11 @@ module Gitrb
|
|
242
262
|
|
243
263
|
@logger.debug "gitrb: #{cmd}"
|
244
264
|
|
265
|
+
# Read in binary mode (ascii-8bit) and convert afterwards
|
245
266
|
out = if block_given?
|
246
|
-
|
247
|
-
|
248
|
-
|
267
|
+
IO.popen(cmd, 'rb', &block)
|
268
|
+
else
|
269
|
+
set_encoding IO.popen(cmd, 'rb') {|io| io.read }
|
249
270
|
end
|
250
271
|
|
251
272
|
if $?.exitstatus > 0
|
@@ -385,7 +406,7 @@ module Gitrb
|
|
385
406
|
end
|
386
407
|
|
387
408
|
def legacy_loose_object?(buf)
|
388
|
-
|
409
|
+
buf[0].ord == 0x78 && ((buf[0].ord << 8) | buf[1].ord) % 31 == 0
|
389
410
|
end
|
390
411
|
|
391
412
|
end
|
data/lib/gitrb/tag.rb
CHANGED
@@ -14,6 +14,7 @@ module Gitrb
|
|
14
14
|
|
15
15
|
def parse(data)
|
16
16
|
headers, @message = data.split("\n\n", 2)
|
17
|
+
repository.set_encoding(@message)
|
17
18
|
|
18
19
|
headers.split("\n").each do |header|
|
19
20
|
key, value = header.split(' ', 2)
|
@@ -21,9 +22,9 @@ module Gitrb
|
|
21
22
|
when 'type'
|
22
23
|
@tagtype = value
|
23
24
|
when 'object'
|
24
|
-
@object = Reference.new(:repository => repository, :id => repository.
|
25
|
+
@object = Reference.new(:repository => repository, :id => repository.set_encoding(value))
|
25
26
|
when 'tagger'
|
26
|
-
@tagger = User.parse(repository.
|
27
|
+
@tagger = User.parse(repository.set_encoding(value))
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
data/lib/gitrb/tree.rb
CHANGED
@@ -24,8 +24,8 @@ module Gitrb
|
|
24
24
|
|
25
25
|
# Set new repository (modified flag is reset)
|
26
26
|
def id=(id)
|
27
|
-
super
|
28
27
|
@modified = false
|
28
|
+
super
|
29
29
|
end
|
30
30
|
|
31
31
|
# Has this tree been modified?
|
@@ -36,7 +36,7 @@ module Gitrb
|
|
36
36
|
def dump
|
37
37
|
@children.to_a.sort {|a,b| a.first <=> b.first }.map do |name, child|
|
38
38
|
child.save if !(Reference === child) || child.resolved?
|
39
|
-
"#{child.mode} #{name}\0#{[child.id].pack("H*")}"
|
39
|
+
"#{child.mode} #{name}\0#{repository.set_encoding [child.id].pack("H*")}"
|
40
40
|
end.join
|
41
41
|
end
|
42
42
|
|
@@ -137,9 +137,9 @@ module Gitrb
|
|
137
137
|
@children.clear
|
138
138
|
data = StringIO.new(data)
|
139
139
|
while !data.eof?
|
140
|
-
mode = repository.
|
141
|
-
name = repository.
|
142
|
-
id = repository.
|
140
|
+
mode = repository.set_encoding Util.read_bytes_until(data, ' ')
|
141
|
+
name = repository.set_encoding Util.read_bytes_until(data, "\0")
|
142
|
+
id = repository.set_encoding data.read(20).unpack("H*").first
|
143
143
|
@children[name] = Reference.new(:repository => repository, :id => id, :mode => mode)
|
144
144
|
end
|
145
145
|
end
|
data/lib/gitrb/util.rb
CHANGED
data/test/repository_spec.rb
CHANGED
@@ -17,9 +17,40 @@ describe Gitrb do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'should fail to initialize without a valid git repository' do
|
20
|
-
lambda
|
20
|
+
lambda do
|
21
21
|
Gitrb::Repository.new(:path => '/')
|
22
|
-
|
22
|
+
end.should raise_error(ArgumentError)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should put and get objects by sha' do
|
26
|
+
blob1 = repo.put(Gitrb::Blob.new(:data => 'Hello'))
|
27
|
+
blob2 = repo.put(Gitrb::Blob.new(:data => 'World'))
|
28
|
+
|
29
|
+
repo.get(blob1.id).should === blob1
|
30
|
+
repo.get(blob1.id[0..4]).should === blob1
|
31
|
+
repo.get(blob1.id[0..10]).should === blob1
|
32
|
+
|
33
|
+
repo.get(blob2.id).should === blob2
|
34
|
+
repo.get(blob2.id[0..4]).should === blob2
|
35
|
+
repo.get(blob2.id[0..10]).should === blob2
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should find commits by revision' do
|
39
|
+
repo.root['a'] = Gitrb::Blob.new(:data => 'Hello')
|
40
|
+
commit1 = repo.commit
|
41
|
+
|
42
|
+
repo.get('HEAD').should === commit1
|
43
|
+
repo.get('master').should === commit1
|
44
|
+
lambda { repo.get('HEAD^') }.should raise_error(Gitrb::NotFound)
|
45
|
+
|
46
|
+
repo.root['a'] = Gitrb::Blob.new(:data => 'World')
|
47
|
+
commit2 = repo.commit
|
48
|
+
|
49
|
+
repo.get('master').should === commit2
|
50
|
+
repo.get('HEAD').should === commit2
|
51
|
+
repo.get('HEAD^').should === commit1
|
52
|
+
repo.get('HEAD~').should === commit1
|
53
|
+
lambda { repo.get('HEAD^^') }.should raise_error(Gitrb::NotFound)
|
23
54
|
end
|
24
55
|
|
25
56
|
it 'should find modified entries' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitrb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Mendler
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-12-
|
12
|
+
date: 2009-12-22 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|