gitrb 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|