← Back to team overview

dulwich-users team mailing list archive

[PATCH 12/33] pack: Allow write_pack_object to compute a SHA.

 

From: Dave Borowitz <dborowitz@xxxxxxxxxx>

Change-Id: Iaf0bc57ffe7533cba0167b2694363fcffc2ddb28
---
 NEWS                       |    3 +++
 dulwich/pack.py            |    4 +++-
 dulwich/tests/test_pack.py |   32 ++++++++++++++++++++++++++++++--
 3 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index 080d74b..41fd821 100644
--- a/NEWS
+++ b/NEWS
@@ -41,6 +41,9 @@
   * PackObjectIterator was removed; its functionality is still exposed by
     PackData.iterobjects. (Dave Borowitz)
 
+  * Add a sha arg to write_pack_object to incrementally compute a SHA.
+    (Dave Borowitz)
+
  TEST CHANGES
 
   * If setuptools is installed, "python setup.py test" will now run the testsuite.
diff --git a/dulwich/pack.py b/dulwich/pack.py
index 99fff66..10da626 100644
--- a/dulwich/pack.py
+++ b/dulwich/pack.py
@@ -1242,7 +1242,7 @@ class SHA1Writer(object):
         return self.f.tell()
 
 
-def write_pack_object(f, type, object):
+def write_pack_object(f, type, object, sha=None):
     """Write pack object to a file.
 
     :param f: File to write to
@@ -1276,6 +1276,8 @@ def write_pack_object(f, type, object):
         packed_data_hdr += basename
     packed_data = packed_data_hdr + zlib.compress(object)
     f.write(packed_data)
+    if sha is not None:
+        sha.update(packed_data)
     return (zlib.crc32(packed_data) & 0xffffffff)
 
 
diff --git a/dulwich/tests/test_pack.py b/dulwich/tests/test_pack.py
index 5b2c879..cf2caea 100644
--- a/dulwich/tests/test_pack.py
+++ b/dulwich/tests/test_pack.py
@@ -26,6 +26,9 @@ import shutil
 import tempfile
 import zlib
 
+from dulwich._compat import (
+    make_sha,
+    )
 from dulwich.errors import (
     ChecksumMismatch,
     )
@@ -63,6 +66,7 @@ from dulwich.pack import (
     SHA1Writer,
     write_pack_object,
     write_pack,
+    unpack_object,
     DeltaChainIterator,
     )
 from dulwich.tests import (
@@ -376,14 +380,38 @@ class TestPack(PackTests):
         self.assertEquals(pack1_sha, p.name())
 
 
-class WritePackHeaderTests(TestCase):
+class WritePackTests(TestCase):
 
-    def test_simple(self):
+    def test_write_pack_header(self):
         f = StringIO()
         write_pack_header(f, 42)
         self.assertEquals('PACK\x00\x00\x00\x02\x00\x00\x00*',
                 f.getvalue())
 
+    def test_write_pack_object(self):
+        f = StringIO()
+        f.write('header')
+        offset = f.tell()
+        crc32 = write_pack_object(f, Blob.type_num, 'blob')
+        self.assertEqual(crc32, zlib.crc32(f.getvalue()[6:]) & 0xffffffff)
+
+        f.write('x')  # unpack_object needs extra trailing data.
+        f.seek(offset)
+        comp_len = len(f.getvalue()) - offset - 1
+        self.assertEqual((Blob.type_num, ['blob'], comp_len, crc32, 'x'),
+                         unpack_object(f.read, compute_crc32=True))
+
+    def test_write_pack_object_sha(self):
+        f = StringIO()
+        f.write('header')
+        offset = f.tell()
+        sha_a = make_sha('foo')
+        sha_b = sha_a.copy()
+        write_pack_object(f, Blob.type_num, 'blob', sha=sha_a)
+        self.assertNotEqual(sha_a.digest(), sha_b.digest())
+        sha_b.update(f.getvalue()[offset:])
+        self.assertEqual(sha_a.digest(), sha_b.digest())
+
 
 pack_checksum = hex_to_sha('721980e866af9a5f93ad674144e1459b8ba3e7b7')
 
-- 
1.7.3.1



References