georgi-git_store 0.2.1 → 0.2.3

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/git_store.gemspec CHANGED
@@ -1,7 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'git_store'
3
- s.version = '0.2.1'
4
- s.date = '2008-12-17'
3
+ s.version = '0.2.3'
5
4
  s.summary = 'a simple data store based on git'
6
5
  s.author = 'Matthias Georgi'
7
6
  s.email = 'matti.georgi@gmail.com'
@@ -13,7 +13,15 @@ require 'zlib'
13
13
 
14
14
  class GitStore
15
15
  PACK_SIGNATURE = "PACK"
16
- PACK_IDX_SIGNATURE = "\377tOc"
16
+ PACK_IDX_SIGNATURE = "\377tOc"
17
+ 85
18
+ OBJ_NONE = 0
19
+ OBJ_COMMIT = 1
20
+ OBJ_TREE = 2
21
+ OBJ_BLOB = 3
22
+ OBJ_TAG = 4
23
+
24
+ OBJ_TYPES = [nil, 'commit', 'tree', 'blob', 'tag'].freeze
17
25
 
18
26
  class Mmap
19
27
  def initialize(file, version = 1)
@@ -111,8 +119,10 @@ class GitStore
111
119
 
112
120
  def with_packfile
113
121
  packfile = File.open(@name)
114
- yield packfile
122
+ result = yield packfile
115
123
  packfile.close
124
+
125
+ result
116
126
  end
117
127
 
118
128
  def cache_objects
@@ -272,14 +282,12 @@ class GitStore
272
282
  private :find_object
273
283
 
274
284
  def parse_object(offset)
275
- obj = nil
276
- with_packfile do |packfile|
277
- data, type = unpack_object(packfile, offset)
278
- obj = RawObject.new(OBJ_TYPES[type], data)
285
+ data, type = with_packfile do |packfile|
286
+ unpack_object(packfile, offset)
279
287
  end
280
- obj
288
+
289
+ return data, OBJ_TYPES[type]
281
290
  end
282
- protected :parse_object
283
291
 
284
292
  def unpack_object(packfile, offset, options = {})
285
293
  obj_offset = offset
@@ -1,5 +1,3 @@
1
- require 'strscan'
2
-
3
1
  class GitStore
4
2
 
5
3
  class Tree
@@ -50,6 +48,7 @@ class GitStore
50
48
  def load_from_disk
51
49
  dir = File.join(store.path, self.path)
52
50
  entries = Dir.entries(dir) - ['.', '..']
51
+
53
52
  @table = entries.inject({}) do |hash, name|
54
53
  if name[-1, 1] != '~' && name[0, 1] != '.'
55
54
  path = "#{dir}/#{name}"
@@ -71,11 +70,13 @@ class GitStore
71
70
  #
72
71
  # Return an array of [mode, name, id] entries.
73
72
  def read_contents(data)
74
- scanner = StringScanner.new(data)
75
73
  contents = []
76
-
77
- while scanner.scan(/(.*?) (.*?)\0(.{20})/m)
78
- contents << [scanner[1], scanner[2], scanner[3].unpack("H*").first]
74
+
75
+ while data.size > 0
76
+ mode, data = data.split(" ", 2)
77
+ name, data = data.split("\0", 2)
78
+ id = data.slice!(0, 20).unpack("H*").first
79
+ contents << [ mode, name, id ]
79
80
  end
80
81
 
81
82
  contents
data/lib/git_store.rb CHANGED
@@ -43,6 +43,7 @@ class GitStore
43
43
  @path = path.chomp('/')
44
44
  @branch = branch
45
45
  @root = Tree.new(self)
46
+ @packs = {}
46
47
 
47
48
  load_packs("#{path}/.git/objects/pack")
48
49
  load
@@ -210,26 +211,18 @@ class GitStore
210
211
 
211
212
  if File.exists?(path)
212
213
  buf = open(path, "rb") { |f| f.read }
214
+
215
+ raise if not legacy_loose_object?(buf)
216
+
217
+ header, content = Zlib::Inflate.inflate(buf).split(/\0/, 2)
218
+ type, size = header.split(/ /, 2)
213
219
  else
214
- get_object_from_pack(id)
220
+ content, type = get_object_from_pack(id)
215
221
  end
216
222
 
217
- raise if not legacy_loose_object?(buf)
218
-
219
- header, content = Zlib::Inflate.inflate(buf).split(/\0/, 2)
220
- type, size = header.split(/ /, 2)
221
-
222
- raise if size.to_i != content.size
223
-
224
223
  return content, type
225
224
  end
226
225
 
227
- def get_object_from_pack(id)
228
- packs.each do |pack|
229
- data = pack[id] and return data
230
- end
231
- end
232
-
233
226
  # Returns the hash value of an object string.
234
227
  def sha(str)
235
228
  Digest::SHA1.hexdigest(str)[0, 40]
@@ -244,7 +237,7 @@ class GitStore
244
237
  data = header + content
245
238
 
246
239
  id = sha(data)
247
- path = object_path(id)
240
+ path = object_path(id)
248
241
 
249
242
  unless File.exists?(path)
250
243
  FileUtils.mkpath(File.dirname(path))
@@ -258,14 +251,27 @@ class GitStore
258
251
 
259
252
  def legacy_loose_object?(buf)
260
253
  word = (buf[0] << 8) + buf[1]
254
+
261
255
  buf[0] == 0x78 && word % 31 == 0
262
256
  end
263
257
 
258
+ def get_object_from_pack(id)
259
+ pack, offset = @packs[id]
260
+
261
+ pack.parse_object(offset) if pack
262
+ end
263
+
264
264
  def load_packs(path)
265
265
  if File.directory?(path)
266
- Dir.open(path) do |dir|
266
+ Dir.open(path) do |dir|
267
267
  entries = dir.select { |entry| entry =~ /\.pack$/i }
268
- @packs = entries.map { |entry| PackStorage.new(File.join(path, entry)) }
268
+ entries.each do |entry|
269
+ pack = PackStorage.new(File.join(path, entry))
270
+ pack.each_entry do |id, offset|
271
+ id = id.unpack("H*").first
272
+ @packs[id] = [pack, offset]
273
+ end
274
+ end
269
275
  end
270
276
  end
271
277
  end
@@ -1,6 +1,4 @@
1
1
  require 'git_store'
2
- require 'yaml'
3
- require 'pp'
4
2
 
5
3
  describe GitStore do
6
4
 
@@ -74,7 +72,7 @@ describe GitStore do
74
72
  it 'should load a repo' do
75
73
  file 'a', 'Hello'
76
74
  file 'b', 'World'
77
-
75
+
78
76
  store.load
79
77
 
80
78
  store['a'].should == 'Hello'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: georgi-git_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthias Georgi
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-12-17 00:00:00 -08:00
12
+ date: 2009-02-25 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies: []
15
15