Kiln » Dependencies » Dulwich Read More
Clone URL:  
Pushed to one repository · View In Graph Contained in master-1, master-0, and 0.9.4

Add add_pack and add_thin_pack methods to MemoryObjectStore.

Closes #97.

Signed-off-by: Jelmer Vernooij <jelmer@samba.org>

Conflicts:
NEWS

Changeset 1b63e1e19b5b

Parent 775ea0a837fe

committed by Jelmer Vernooij

authored by David Bennett

Changes to 3 files · Browse files at 1b63e1e19b5b Showing diff from parent 775ea0a837fe Diff from another changeset...

Change 1 of 1 Show Entire File NEWS Stacked
 
21
22
23
 
 
 
24
25
26
 
21
22
23
24
25
26
27
28
29
@@ -21,6 +21,9 @@
    * Support thin packs in Pack.iterobjects() and Pack.get_raw().   (William Grant) + + * Add `MemoryObjectStore.add_pack` and `MemoryObjectStore.add_thin_pack` methods. + (David Bennett)    0.9.0 2013-05-31  
 
21
22
23
 
24
25
26
 
50
51
52
 
53
54
55
 
724
725
726
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
727
728
729
 
21
22
23
24
25
26
27
 
51
52
53
54
55
56
57
 
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
@@ -21,6 +21,7 @@
 """Git object store interfaces and implementation."""     +from cStringIO import StringIO  import errno  import itertools  import os @@ -50,6 +51,7 @@
 from dulwich.pack import (   Pack,   PackData, + PackInflater,   iter_sha1,   write_pack_header,   write_pack_index_v2, @@ -724,6 +726,65 @@
  """   for obj, path in objects:   self._data[obj.id] = obj + + def add_pack(self): + """Add a new pack to this object store. + + Because this object store doesn't support packs, we extract and add the + individual objects. + + :return: Fileobject to write to and a commit function to + call when the pack is finished. + """ + f = StringIO() + def commit(): + p = PackData.from_file(StringIO(f.getvalue()), f.tell()) + f.close() + for obj in PackInflater.for_pack_data(p): + self._data[obj.id] = obj + return f, commit + + def _complete_thin_pack(self, f, indexer): + """Complete a thin pack by adding external references. + + :param f: Open file object for the pack. + :param indexer: A PackIndexer for indexing the pack. + """ + entries = list(indexer) + + # Update the header with the new number of objects. + f.seek(0) + write_pack_header(f, len(entries) + len(indexer.ext_refs())) + + # Rescan the rest of the pack, computing the SHA with the new header. + new_sha = compute_file_sha(f, end_ofs=-20) + + # Complete the pack. + for ext_sha in indexer.ext_refs(): + assert len(ext_sha) == 20 + type_num, data = self.get_raw(ext_sha) + write_pack_object(f, type_num, data, sha=new_sha) + pack_sha = new_sha.digest() + f.write(pack_sha) + + def add_thin_pack(self, read_all, read_some): + """Add a new thin pack to this object store. + + Thin packs are packs that contain deltas with parents that exist outside + the pack. Because this object store doesn't support packs, we extract + and add the individual objects. + + :param read_all: Read function that blocks until the number of requested + bytes are read. + :param read_some: Read function that returns at least one byte, but may + not return the number of bytes requested. + """ + f, commit = self.add_pack() + indexer = PackIndexer(f, resolve_ext_ref=self.get_raw) + copier = PackStreamCopier(read_all, read_some, f, delta_iter=indexer) + copier.verify() + self._complete_thin_pack(f, indexer) + commit()      class ObjectImporter(object):
 
194
195
196
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
198
199
 
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
@@ -194,6 +194,27 @@
  def setUp(self):   TestCase.setUp(self)   self.store = MemoryObjectStore() + + def test_add_pack(self): + o = MemoryObjectStore() + f, commit = o.add_pack() + b = make_object(Blob, data="more yummy data") + write_pack_objects(f, [(b, None)]) + commit() + + def test_add_thin_pack(self): + o = MemoryObjectStore() + blob = make_object(Blob, data='yummy data') + o.add_object(blob) + + f = StringIO() + entries = build_pack(f, [ + (REF_DELTA, (blob.id, 'more yummy data')), + ], store=o) + o.add_thin_pack(f.read, None) + packed_blob_sha = sha_to_hex(entries[0][3]) + self.assertEqual((Blob.type_num, 'more yummy data'), + o.get_raw(packed_blob_sha))      class PackBasedObjectStoreTests(ObjectStoreTests):