|
@@ -589,8 +589,8 @@ def write_pack_data(f, objects, num_objects, window=10):
|
|
|
|
|
|
|
|
|
|
magic = []
|
|
magic = []
|
|
- for o in recency:
|
|
+ for obj, path in recency:
|
|
- magic.append( (o._num_type, "filename", 1, -len(o.as_raw_string()[1]), o) )
|
|
+ magic.append( (obj.type, path, 1, -len(obj.as_raw_string()[1]), obj) )
|
|
magic.sort()
|
|
magic.sort()
|
|
|
|
|
|
|
|
|
|
@@ -603,17 +603,22 @@ def write_pack_data(f, objects, num_objects, window=10):
|
|
f.write("PACK")
|
|
f.write("PACK")
|
|
f.write(struct.pack(">L", 2))
|
|
f.write(struct.pack(">L", 2))
|
|
f.write(struct.pack(">L", num_objects))
|
|
f.write(struct.pack(">L", num_objects))
|
|
- for o in recency:
|
|
+ for o, path in recency:
|
|
sha1 = o.sha().digest()
|
|
sha1 = o.sha().digest()
|
|
crc32 = o.crc32()
|
|
crc32 = o.crc32()
|
|
- t, raw = o.as_raw_string()
|
|
+ orig_t, raw = o.as_raw_string()
|
|
winner = raw
|
|
winner = raw
|
|
- for i in range(1, window+1):
|
|
+ t = orig_t
|
|
- base = magic[offs[sha1] - i]
|
|
+
|
|
- delta = create_delta(base, raw)
|
|
+
|
|
- if len(delta) < len(winner):
|
|
+
|
|
- winner = delta
|
|
+
|
|
- offset = write_pack_object(f, t, raw)
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ offset = write_pack_object(f, t, winner)
|
|
entries.append((sha1, offset, crc32))
|
|
entries.append((sha1, offset, crc32))
|
|
return entries, f.write_sha()
|
|
return entries, f.write_sha()
|
|
|
|
|
|
@@ -647,7 +652,6 @@ def create_delta(base_buf, target_buf):
|
|
assert isinstance(base_buf, str)
|
|
assert isinstance(base_buf, str)
|
|
assert isinstance(target_buf, str)
|
|
assert isinstance(target_buf, str)
|
|
out_buf = ""
|
|
out_buf = ""
|
|
-
|
|
|
|
|
|
|
|
def encode_size(size):
|
|
def encode_size(size):
|
|
ret = ""
|
|
ret = ""
|
|
@@ -661,36 +665,29 @@ def create_delta(base_buf, target_buf):
|
|
return ret
|
|
return ret
|
|
out_buf += encode_size(len(base_buf))
|
|
out_buf += encode_size(len(base_buf))
|
|
out_buf += encode_size(len(target_buf))
|
|
out_buf += encode_size(len(target_buf))
|
|
-
|
|
|
|
|
|
|
|
seq = difflib.SequenceMatcher(a=base_buf, b=target_buf)
|
|
seq = difflib.SequenceMatcher(a=base_buf, b=target_buf)
|
|
for opcode, i1, i2, j1, j2 in seq.get_opcodes():
|
|
for opcode, i1, i2, j1, j2 in seq.get_opcodes():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
|
if opcode == "equal":
|
|
if opcode == "equal":
|
|
|
|
|
|
|
|
|
|
scratch = ""
|
|
scratch = ""
|
|
op = 0x80
|
|
op = 0x80
|
|
-
|
|
|
|
o = i1
|
|
o = i1
|
|
for i in range(4):
|
|
for i in range(4):
|
|
- if o & 0x000000ff << i*8:
|
|
+ if o & 0xff << i*8:
|
|
scratch += chr(o >> i)
|
|
scratch += chr(o >> i)
|
|
op |= 1 << i
|
|
op |= 1 << i
|
|
-
|
|
|
|
s = i2 - i1
|
|
s = i2 - i1
|
|
for i in range(2):
|
|
for i in range(2):
|
|
- if s & 0x000000ff << i*8:
|
|
+ if s & 0xff << i*8:
|
|
scratch += chr(s >> i)
|
|
scratch += chr(s >> i)
|
|
op |= 1 << (4+i)
|
|
op |= 1 << (4+i)
|
|
-
|
|
|
|
out_buf += chr(op)
|
|
out_buf += chr(op)
|
|
out_buf += scratch
|
|
out_buf += scratch
|
|
-
|
|
|
|
-
|
|
|
|
if opcode == "replace" or opcode == "insert":
|
|
if opcode == "replace" or opcode == "insert":
|
|
|
|
|
|
|
|
|
|
@@ -703,7 +700,6 @@ def create_delta(base_buf, target_buf):
|
|
o += 127
|
|
o += 127
|
|
out_buf += chr(s)
|
|
out_buf += chr(s)
|
|
out_buf += target_buf[o:o+s]
|
|
out_buf += target_buf[o:o+s]
|
|
-
|
|
|
|
return out_buf
|
|
return out_buf
|
|
|
|
|
|
|
|
|
|
@@ -852,8 +848,6 @@ class Pack(object):
|
|
return (self.idx.object_index(sha1) is not None)
|
|
return (self.idx.object_index(sha1) is not None)
|
|
|
|
|
|
def get_raw(self, sha1, resolve_ref=None):
|
|
def get_raw(self, sha1, resolve_ref=None):
|
|
- if resolve_ref is None:
|
|
|
|
- resolve_ref = self.get_raw
|
|
|
|
offset = self.idx.object_index(sha1)
|
|
offset = self.idx.object_index(sha1)
|
|
if offset is None:
|
|
if offset is None:
|
|
raise KeyError(sha1)
|
|
raise KeyError(sha1)
|
|
@@ -868,12 +862,16 @@ class Pack(object):
|
|
type, uncomp = self.get_raw(sha1)
|
|
type, uncomp = self.get_raw(sha1)
|
|
return ShaFile.from_raw_string(type, uncomp)
|
|
return ShaFile.from_raw_string(type, uncomp)
|
|
|
|
|
|
- def iterobjects(self):
|
|
+ def iterobjects(self, get_raw=None):
|
|
|
|
+ if get_raw is None:
|
|
|
|
+ def get_raw(x):
|
|
|
|
+ raise KeyError(x)
|
|
for offset, type, obj in self.data.iterobjects():
|
|
for offset, type, obj in self.data.iterobjects():
|
|
assert isinstance(offset, int)
|
|
assert isinstance(offset, int)
|
|
yield ShaFile.from_raw_string(
|
|
yield ShaFile.from_raw_string(
|
|
- *resolve_object(offset, type, obj, self.get_raw,
|
|
+ *resolve_object(offset, type, obj,
|
|
- self.data.get_object_at))
|
|
+ get_raw,
|
|
|
|
+ self.data.get_object_at))
|
|
|
|
|
|
|
|
|
|
def load_packs(path):
|
|
def load_packs(path):
|