DeltaChainIterator: fix a corner case where an object is inflated as an object alread...
authorDamien Tournoud <damien@commerceguys.com>
Tue, 15 Apr 2014 14:57:09 +0000 (16:57 +0200)
committerJelmer Vernooij <jelmer@samba.org>
Wed, 16 Apr 2014 00:56:15 +0000 (02:56 +0200)
dulwich/pack.py
dulwich/tests/test_pack.py

index 1fffa8e157f20dbce29bcca6ed0fde650c87b5fb..569aff42796c0c76356de02adca413b07a0cf1eb 100644 (file)
@@ -1264,6 +1264,8 @@ class DeltaChainIterator(object):
             return
 
         for base_sha, pending in sorted(self._pending_ref.iteritems()):
+            if base_sha not in self._pending_ref:
+                continue
             try:
                 type_num, chunks = self._resolve_ext_ref(base_sha)
             except KeyError:
index 6227f657b151d3a9af16c569d2d938c0d5687798..7be70142e4c7cd7ad1b7f32cd1f5cf7da8ccb0b4 100644 (file)
@@ -956,6 +956,22 @@ class DeltaChainIteratorTests(TestCase):
         self.assertEntriesMatch([1, 0], entries, pack_iter)
         self.assertEqual([hex_to_sha(blob.id)], pack_iter.ext_refs())
 
+    def test_ext_ref_chain_degenerate(self):
+        # Test a degenerate case where the sender is sending a REF_DELTA
+        # object that expands to an object already in the repository.
+        blob, = self.store_blobs(['blob'])
+        blob2, = self.store_blobs(['blob2'])
+        assert blob.id < blob2.id
+
+        f = StringIO()
+        entries = build_pack(f, [
+          (REF_DELTA, (blob.id, 'blob2')),
+          (REF_DELTA, (0, 'blob3')),
+          ], store=self.store)
+        pack_iter = self.make_pack_iter(f)
+        self.assertEntriesMatch([0, 1], entries, pack_iter)
+        self.assertEqual([hex_to_sha(blob.id)], pack_iter.ext_refs())
+
     def test_ext_ref_multiple_times(self):
         blob, = self.store_blobs(['blob'])
         f = BytesIO()