132
132
name = self.encode_name(repo_kind, revision_id, file_id)
133
133
encoded_metadata = bencode.bencode(metadata)
134
self._container.add_bytes_record(encoded_metadata, [name])
134
self._container.add_bytes_record(encoded_metadata, [(name, )])
135
135
if metadata['storage_kind'] != 'header':
136
136
self._container.add_bytes_record(bytes, [])
147
def __init__(self, fileobj):
147
def __init__(self, fileobj, stream_input=True):
150
:param fileobj: a file containing a bzip-encoded container
151
:param stream_input: If True, the BundleReader stream input rather than
152
reading it all into memory at once. Reading it into memory all at
153
once is (currently) faster.
148
155
line = fileobj.readline()
150
157
fileobj.readline()
151
158
self.patch_lines = []
152
self._container = pack.ContainerReader(
153
iterablefile.IterableFile(self.iter_decode(fileobj)))
160
source_file = iterablefile.IterableFile(self.iter_decode(fileobj))
162
source_file = StringIO(bz2.decompress(fileobj.read()))
163
self._container = pack.ContainerReader(source_file)
156
166
def iter_decode(fileobj):
382
392
def install(self, repository):
383
393
return self.install_revisions(repository)
385
def install_revisions(self, repository):
386
"""Install this bundle's revisions into the specified repository"""
395
def install_revisions(self, repository, stream_input=True):
396
"""Install this bundle's revisions into the specified repository
398
:param target_repo: The repository to install into
399
:param stream_input: If True, will stream input rather than reading it
400
all into memory at once. Reading it into memory all at once is
387
403
repository.lock_write()
389
ri = RevisionInstaller(self.get_bundle_reader(),
405
ri = RevisionInstaller(self.get_bundle_reader(stream_input),
390
406
self._serializer, repository)
391
407
return ri.install()
400
416
return None, self.target, 'inapplicable'
402
def get_bundle_reader(self):
418
def get_bundle_reader(self, stream_input=True):
419
"""Return a new BundleReader for the associated bundle
421
:param stream_input: If True, the BundleReader stream input rather than
422
reading it all into memory at once. Reading it into memory all at
423
once is (currently) faster.
403
425
self._fileobj.seek(0)
404
return BundleReader(self._fileobj)
426
return BundleReader(self._fileobj, stream_input)
406
428
def _get_real_revisions(self):
407
429
if self.__real_revisions is None:
448
470
current_file = None
449
471
current_versionedfile = None
450
472
pending_file_records = []
474
pending_inventory_records = []
451
475
added_inv = set()
452
476
target_revision = None
453
477
for bytes, metadata, repo_kind, revision_id, file_id in\
455
479
if repo_kind == 'info':
456
480
assert self._info is None
457
481
self._handle_info(metadata)
458
if repo_kind != 'file':
482
if ((repo_kind, file_id) != ('file', current_file) and
483
len(pending_file_records) > 0):
459
484
self._install_mp_records(current_versionedfile,
460
485
pending_file_records)
461
486
current_file = None
462
487
current_versionedfile = None
463
488
pending_file_records = []
464
if repo_kind == 'inventory':
465
self._install_inventory(revision_id, metadata, bytes)
466
if repo_kind == 'revision':
467
target_revision = revision_id
468
self._install_revision(revision_id, metadata, bytes)
469
if repo_kind == 'signature':
470
self._install_signature(revision_id, metadata, bytes)
489
if len(pending_inventory_records) > 0 and repo_kind != 'inventory':
490
self._install_inventory_records(inventory_vf,
491
pending_inventory_records)
492
pending_inventory_records = []
493
if repo_kind == 'inventory':
494
if inventory_vf is None:
495
inventory_vf = self._repository.get_inventory_weave()
496
if revision_id not in inventory_vf:
497
pending_inventory_records.append((revision_id, metadata,
499
if repo_kind == 'revision':
500
target_revision = revision_id
501
self._install_revision(revision_id, metadata, bytes)
502
if repo_kind == 'signature':
503
self._install_signature(revision_id, metadata, bytes)
471
504
if repo_kind == 'file':
472
if file_id != current_file:
473
self._install_mp_records(current_versionedfile,
474
pending_file_records)
475
current_file = file_id
505
current_file = file_id
506
if current_versionedfile is None:
476
507
current_versionedfile = \
477
508
self._repository.weave_store.get_weave_or_empty(
478
509
file_id, self._repository.get_transaction())
501
532
records if r not in versionedfile]
502
533
versionedfile.add_mpdiffs(vf_records)
504
def _install_inventory(self, revision_id, metadata, text):
505
vf = self._repository.get_inventory_weave()
506
if revision_id in vf:
508
parent_ids = metadata['parents']
535
def _install_inventory_records(self, vf, records):
509
536
if self._info['serializer'] == self._repository._serializer.format_num:
510
return self._install_mp_records(vf, [(revision_id, metadata,
512
parents = [self._repository.get_inventory(p)
514
parent_texts = [self._source_serializer.write_inventory_to_string(p)
516
target_lines = multiparent.MultiParent.from_patch(text).to_lines(
518
sha1 = osutils.sha_strings(target_lines)
519
if sha1 != metadata['sha1']:
520
raise errors.BadBundle("Can't convert to target format")
521
target_inv = self._source_serializer.read_inventory_from_string(
522
''.join(target_lines))
523
self._handle_root(target_inv, parent_ids)
525
self._repository.add_inventory(revision_id, target_inv, parent_ids)
526
except errors.UnsupportedInventoryKind:
527
raise errors.IncompatibleRevision(repr(self._repository))
537
return self._install_mp_records(vf, records)
538
for revision_id, metadata, bytes in records:
539
parent_ids = metadata['parents']
540
parents = [self._repository.get_inventory(p)
542
p_texts = [self._source_serializer.write_inventory_to_string(p)
544
target_lines = multiparent.MultiParent.from_patch(bytes).to_lines(
546
sha1 = osutils.sha_strings(target_lines)
547
if sha1 != metadata['sha1']:
548
raise errors.BadBundle("Can't convert to target format")
549
target_inv = self._source_serializer.read_inventory_from_string(
550
''.join(target_lines))
551
self._handle_root(target_inv, parent_ids)
553
self._repository.add_inventory(revision_id, target_inv,
555
except errors.UnsupportedInventoryKind:
556
raise errors.IncompatibleRevision(repr(self._repository))
529
558
def _handle_root(self, target_inv, parent_ids):
530
559
revision_id = target_inv.revision_id