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 CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'gitrb'
3
- s.version = '0.0.5'
3
+ s.version = '0.0.6'
4
4
  s.summary = 'Pure ruby git implementation'
5
5
  s.author = 'Daniel Mendler'
6
6
  s.email = 'mail@daniel-mendler.de'
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.encode(@message)
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.encode(value))
57
+ @parent << Reference.new(:repository => repository, :id => repository.set_encoding(value))
58
58
  when 'author'
59
- @author = User.parse(repository.encode(value))
59
+ @author = User.parse(repository.set_encoding(value))
60
60
  when 'committer'
61
- @committer = User.parse(repository.encode(value))
61
+ @committer = User.parse(repository.set_encoding(value))
62
62
  when 'tree'
63
- @tree = Reference.new(:repository => repository, :id => repository.encode(value))
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 = Util.ord(sha1, 0)
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 = Util.ord(packfile.read(1), 0)
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 = Util.ord(packfile.read(1), 0)
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 = Util.ord(data, i)
232
+ c = data[i].ord
233
233
  base_offset = c & 0x7f
234
234
  while c & 0x80 != 0
235
- c = Util.ord(data, i += 1)
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 = Util.ord(delta, pos)
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 = Util.ord(delta, pos += 1) if c & 0x01 != 0
288
- cp_off |= Util.ord(delta, pos += 1) << 8 if c & 0x02 != 0
289
- cp_off |= Util.ord(delta, pos += 1) << 16 if c & 0x04 != 0
290
- cp_off |= Util.ord(delta, pos += 1) << 24 if c & 0x08 != 0
291
- cp_size = Util.ord(delta, pos += 1) if c & 0x10 != 0
292
- cp_size |= Util.ord(delta, pos += 1) << 8 if c & 0x20 != 0
293
- cp_size |= Util.ord(delta, pos += 1) << 16 if c & 0x40 != 0
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 = Util.ord(delta, pos)
311
+ c = delta[pos].ord
312
312
  if c == nil
313
313
  raise PackFormatError, 'invalid delta header'
314
314
  end
@@ -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] || 'utf-8'
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
- from = from.id if Commit === from
93
- to = to.id if Commit === to
94
- Diff.new(from, to, git_diff('--full-index', from, to, '--', path))
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
- return nil if id.nil? || id.length < 5
167
- list = @objects.find(id).to_a
168
- return list.first if list.size == 1
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 not unique" if glob.size > 1
176
- path = glob[0]
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, "rb") { |f| f.read }
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
- list = @packs.find(id).to_a
189
- raise NotFound, "Object not found" if list.size != 1
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
- object = Gitrb::Object.factory(type, :repository => self, :id => encode(id), :data => content)
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
- IO.popen(cmd, &block)
247
- else
248
- `#{cmd}`.chomp
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
- Util.ord(buf, 0) == 0x78 && ((Util.ord(buf, 0) << 8) + Util.ord(buf, 1)) % 31 == 0
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.encode(value))
25
+ @object = Reference.new(:repository => repository, :id => repository.set_encoding(value))
25
26
  when 'tagger'
26
- @tagger = User.parse(repository.encode(value))
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.encode Util.read_bytes_until(data, ' ')
141
- name = repository.encode Util.read_bytes_until(data, "\0")
142
- id = repository.encode data.read(20).unpack("H*").first
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
@@ -17,9 +17,5 @@ module Gitrb
17
17
  str
18
18
  end
19
19
  end
20
-
21
- def self.ord(s, i)
22
- s[i].ord
23
- end
24
20
  end
25
21
  end
@@ -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
- }.should raise_error(ArgumentError)
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.5
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-20 00:00:00 +01:00
12
+ date: 2009-12-22 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies: []
15
15