|
@@ -134,28 +134,6 @@ def simple_mmap(f, offset, size, access=mmap.ACCESS_READ):
|
|
|
return ArraySkipper(mem, offset)
|
|
|
|
|
|
|
|
|
-def resolve_object(offset, type, obj, get_ref, get_offset):
|
|
|
- """Resolve an object, possibly resolving deltas when necessary."""
|
|
|
- if not type in (6, 7): # Not a delta
|
|
|
- return type, obj
|
|
|
-
|
|
|
- if type == 6: # offset delta
|
|
|
- (delta_offset, delta) = obj
|
|
|
- assert isinstance(delta_offset, int)
|
|
|
- assert isinstance(delta, str)
|
|
|
- offset = offset-delta_offset
|
|
|
- type, base_obj = get_offset(offset)
|
|
|
- assert isinstance(type, int)
|
|
|
- elif type == 7: # ref delta
|
|
|
- (basename, delta) = obj
|
|
|
- assert isinstance(basename, str) and len(basename) == 20
|
|
|
- assert isinstance(delta, str)
|
|
|
- type, base_obj = get_ref(basename)
|
|
|
- assert isinstance(type, int)
|
|
|
- type, base_text = resolve_object(offset, type, base_obj, get_ref, get_offset)
|
|
|
- return type, apply_delta(base_text, delta)
|
|
|
-
|
|
|
-
|
|
|
class PackIndex(object):
|
|
|
"""An index in to a packfile.
|
|
|
|
|
@@ -367,6 +345,13 @@ def unpack_object(map):
|
|
|
return type, uncomp, comp_len+raw_base
|
|
|
|
|
|
|
|
|
+def compute_object_size((num, obj)):
|
|
|
+ if num in (6, 7):
|
|
|
+ return len(obj[1])
|
|
|
+ assert isinstance(obj, str)
|
|
|
+ return len(obj)
|
|
|
+
|
|
|
+
|
|
|
class PackData(object):
|
|
|
"""The data contained in a packfile.
|
|
|
|
|
@@ -432,6 +417,34 @@ class PackData(object):
|
|
|
return make_sha(map[:-20]).digest()
|
|
|
finally:
|
|
|
f.close()
|
|
|
+
|
|
|
+ def resolve_object(self, offset, type, obj, get_ref, get_offset=None):
|
|
|
+ """Resolve an object, possibly resolving deltas when necessary.
|
|
|
+
|
|
|
+ :return: Tuple with object type and contents.
|
|
|
+ """
|
|
|
+ if not type in (6, 7): # Not a delta
|
|
|
+ return type, obj
|
|
|
+
|
|
|
+ if get_offset is None:
|
|
|
+ get_offset = self.get_object_at
|
|
|
+
|
|
|
+ if type == 6: # offset delta
|
|
|
+ (delta_offset, delta) = obj
|
|
|
+ assert isinstance(delta_offset, int)
|
|
|
+ assert isinstance(delta, str)
|
|
|
+ offset = offset-delta_offset
|
|
|
+ type, base_obj = get_offset(offset)
|
|
|
+ assert isinstance(type, int)
|
|
|
+ elif type == 7: # ref delta
|
|
|
+ (basename, delta) = obj
|
|
|
+ assert isinstance(basename, str) and len(basename) == 20
|
|
|
+ assert isinstance(delta, str)
|
|
|
+ type, base_obj = get_ref(basename)
|
|
|
+ assert isinstance(type, int)
|
|
|
+ type, base_text = self.resolve_object(offset, type, base_obj, get_ref)
|
|
|
+ ret = (type, apply_delta(base_text, delta))
|
|
|
+ return ret
|
|
|
|
|
|
def iterobjects(self):
|
|
|
offset = self._header_size
|
|
@@ -468,7 +481,7 @@ class PackData(object):
|
|
|
assert isinstance(type, int)
|
|
|
assert isinstance(obj, tuple) or isinstance(obj, str)
|
|
|
try:
|
|
|
- type, obj = resolve_object(offset, type, obj, get_ref_text,
|
|
|
+ type, obj = self.resolve_object(offset, type, obj, get_ref_text,
|
|
|
at.__getitem__)
|
|
|
except Postpone, (sha, ):
|
|
|
postponed[sha].append((offset, type, obj))
|
|
@@ -516,7 +529,8 @@ class PackData(object):
|
|
|
f = open(self._filename, 'rb')
|
|
|
try:
|
|
|
map = simple_mmap(f, offset, size-offset)
|
|
|
- return unpack_object(map)[:2]
|
|
|
+ ret = unpack_object(map)[:2]
|
|
|
+ return ret
|
|
|
finally:
|
|
|
f.close()
|
|
|
|
|
@@ -884,8 +898,7 @@ class Pack(object):
|
|
|
if isinstance(offset, long):
|
|
|
offset = int(offset)
|
|
|
assert isinstance(offset, int)
|
|
|
- return resolve_object(offset, type, obj, resolve_ref,
|
|
|
- self.data.get_object_at)
|
|
|
+ return self.data.resolve_object(offset, type, obj, resolve_ref)
|
|
|
|
|
|
def __getitem__(self, sha1):
|
|
|
"""Retrieve the specified SHA1."""
|
|
@@ -899,9 +912,7 @@ class Pack(object):
|
|
|
for offset, type, obj, crc32 in self.data.iterobjects():
|
|
|
assert isinstance(offset, int)
|
|
|
yield ShaFile.from_raw_string(
|
|
|
- *resolve_object(offset, type, obj,
|
|
|
- get_raw,
|
|
|
- self.data.get_object_at))
|
|
|
+ *self.data.resolve_object(offset, type, obj, get_raw))
|
|
|
|
|
|
|
|
|
def load_packs(path):
|