ソースを参照

Initial work trying to support deltas.

Jelmer Vernooij 16 年 前
コミット
5544629dc4
4 ファイル変更69 行追加27 行削除
  1. 1 1
      bin/dumppack
  2. 29 3
      dulwich/objects.py
  3. 25 9
      dulwich/pack.py
  4. 14 14
      dulwich/tests/test_pack.py

+ 1 - 1
bin/dumppack

@@ -27,4 +27,4 @@ if not x.check():
 	print "CHECKSUM DOES NOT MATCH"
 print "Length: %d" % len(x)
 for name in x:
-	print "\t%s: %s" % (name, x._idx.object_index(name))
+	print "\t%s: %s" % (name, x[name])

+ 29 - 3
dulwich/objects.py

@@ -30,6 +30,7 @@ from errors import (NotCommitError,
                     )
 
 blob_id = "blob"
+tag_id = "tag"
 tree_id = "tree"
 commit_id = "commit"
 parent_id = "parent"
@@ -193,6 +194,27 @@ class Blob(ShaFile):
     return shafile
 
 
+class Tag(ShaFile):
+  """A Git Tag object."""
+
+  _type = tag_id
+
+  @classmethod
+  def from_file(cls, filename):
+    blob = ShaFile.from_file(filename)
+    if blob._type != cls._type:
+      raise NotBlobError(filename)
+    return blob
+
+  @classmethod
+  def from_string(cls, string):
+    """Create a blob from a string."""
+    shafile = cls()
+    shafile._text = string
+    shafile._update_contents()
+    return shafile
+
+
 class Tree(ShaFile):
   """A Git tree object"""
 
@@ -344,11 +366,15 @@ type_map = {
   blob_id : Blob,
   tree_id : Tree,
   commit_id : Commit,
+  tag_id: Tag,
 }
 
 num_type_map = {
-  1 : Commit,
-  2 : Tree,
-  3 : Blob,
+  0: None,
+  1: Commit,
+  2: Tree,
+  3: Blob,
+  4: Tag,
+  # 5 Is reserved for further expansion
 }
 

+ 25 - 9
dulwich/pack.py

@@ -349,14 +349,7 @@ class PackData(object):
       size += size_part << ((cur_offset * 7) + 4)
       cur_offset += 1
     raw_base = cur_offset+1
-    # The size is the inflated size, so we have no idea what the deflated size
-    # is, so for now give it as much as we have. It should really iterate
-    # feeding it more data if it doesn't decompress, but as we have the whole
-    # thing then just use it.
-    raw = map[raw_base:]
-    uncomp = _decompress(raw)
-    obj = ShaFile.from_raw_string(type, uncomp)
-    return obj
+    return type, map[raw_base:], size
 
 
 class SHA1Writer(object):
@@ -487,4 +480,27 @@ class Pack(object):
         offset = self._idx.object_index(sha1)
         if offset is None:
             raise KeyError(sha1)
-        return self._pack.get_object_at(offset)
+
+        type, raw, size =  self._pack.get_object_at(offset)
+        if type == 6: # offset delta
+            # FIXME: Parse size
+            raw_base = cur_offset+1
+            uncomp = _decompress(raw[raw_offset:])
+            assert size == len(uncomp)
+            raise AssertionError("OFS_DELTA not yet supported")
+        elif type == 7: # ref delta
+            basename = raw[:20]
+            uncomp = _decompress(raw[20:])
+            assert size == len(uncomp)
+            base = self[sha_to_hex(basename)]
+            raise AssertionError("REF_DELTA not yet supported")
+        else:
+            # The size is the inflated size, so we have no idea what the deflated size
+            # is, so for now give it as much as we have. It should really iterate
+            # feeding it more data if it doesn't decompress, but as we have the whole
+            # thing then just use it.
+            uncomp = _decompress(raw)
+            assert len(uncomp) == size
+            obj = ShaFile.from_raw_string(type, uncomp)
+            return obj
+        return 

+ 14 - 14
dulwich/tests/test_pack.py

@@ -98,20 +98,6 @@ class TestPackData(PackTests):
   def test_create_pack(self):
     p = self.get_pack_data(pack1_sha)
 
-  def test_get_object_at(self):
-    """Tests random access for non-delta objects"""
-    p = self.get_pack_data(pack1_sha)
-    idx = self.get_pack_index(pack1_sha)
-    obj = p.get_object_at(idx.object_index(a_sha))
-    self.assertEqual(obj._type, 'blob')
-    self.assertEqual(obj.sha().hexdigest(), a_sha)
-    obj = p.get_object_at(idx.object_index(tree_sha))
-    self.assertEqual(obj._type, 'tree')
-    self.assertEqual(obj.sha().hexdigest(), tree_sha)
-    obj = p.get_object_at(idx.object_index(commit_sha))
-    self.assertEqual(obj._type, 'commit')
-    self.assertEqual(obj.sha().hexdigest(), commit_sha)
-
   def test_pack_len(self):
     p = self.get_pack_data(pack1_sha)
     self.assertEquals(3, len(p))
@@ -139,6 +125,20 @@ class TestPack(PackTests):
         p = self.get_pack(pack1_sha)
         self.assertEquals(set([tree_sha, commit_sha, a_sha]), set(p))
 
+    def test_get_object_at(self):
+        """Tests random access for non-delta objects"""
+        p = self.get_pack(pack1_sha)
+        obj = p[a_sha]
+        self.assertEqual(obj._type, 'blob')
+        self.assertEqual(obj.sha().hexdigest(), a_sha)
+        obj = p[tree_sha]
+        self.assertEqual(obj._type, 'tree')
+        self.assertEqual(obj.sha().hexdigest(), tree_sha)
+        obj = p[commit_sha]
+        self.assertEqual(obj._type, 'commit')
+        self.assertEqual(obj.sha().hexdigest(), commit_sha)
+
+
 
 class TestHexToSha(unittest.TestCase):