3974
3974
new_pack.set_write_cache_size(1024*1024)
3975
delta_deserializer = inventory_delta.InventoryDeltaSerializer()
3976
3975
for substream_type, substream in stream:
3977
3976
if substream_type == 'texts':
3978
3977
self.target_repo.texts.insert_record_stream(substream)
3984
3983
self._extract_and_insert_inventories(
3985
substream, src_serializer,
3986
delta_deserializer.parse_text_bytes)
3984
substream, src_serializer)
3985
elif substream_type == 'inventory-deltas':
3986
self._extract_and_insert_inventory_deltas(
3987
substream, src_serializer)
3987
3988
elif substream_type == 'chk_bytes':
3988
3989
# XXX: This doesn't support conversions, as it assumes the
3989
3990
# conversion was done in the fetch code.
4040
4041
self.target_repo.pack(hint=hint)
4041
4042
return [], set()
4044
def _extract_and_insert_inventory_deltas(self, substream, serializer):
4045
target_rich_root = self.target_repo._format.rich_root_data
4046
target_tree_refs = self.target_repo._format.supports_tree_reference
4047
for record in substream:
4048
# Insert the delta directly
4049
inventory_delta_bytes = record.get_bytes_as('fulltext')
4050
deserialiser = inventory_delta.InventoryDeltaSerializer()
4051
parse_result = deserialiser.parse_text_bytes(inventory_delta_bytes)
4052
basis_id, new_id, rich_root, tree_refs, inv_delta = parse_result
4053
#mutter('inv_delta: %r', inv_delta)
4054
# Make sure the delta is compatible with the target
4055
if rich_root and not target_rich_root:
4056
raise errors.IncompatibleRevision(self.target_repo._format)
4057
if tree_refs and not target_tree_refs:
4058
raise errors.IncompatibleRevision(self.target_repo._format)
4059
#revision_id = new_id[0]
4060
revision_id = new_id
4061
parents = [key[0] for key in record.parents]
4062
self.target_repo.add_inventory_by_delta(
4063
basis_id, inv_delta, revision_id, parents)
4043
4065
def _extract_and_insert_inventories(self, substream, serializer,
4044
4066
parse_delta=None):
4045
4067
"""Generate a new inventory versionedfile in target, converting data.
4050
4072
target_rich_root = self.target_repo._format.rich_root_data
4051
4073
target_tree_refs = self.target_repo._format.supports_tree_reference
4052
4074
for record in substream:
4053
if record.storage_kind == 'inventory-delta':
4054
# Insert the delta directly
4055
delta_tuple = record.get_bytes_as('inventory-delta')
4056
basis_id, new_id, inv_delta, format_flags = delta_tuple
4057
# Make sure the delta is compatible with the target
4058
if format_flags[0] and not target_rich_root:
4059
raise errors.IncompatibleRevision(self.target_repo._format)
4060
if format_flags[1] and not target_tree_refs:
4061
raise errors.IncompatibleRevision(self.target_repo._format)
4062
revision_id = new_id[0]
4063
parents = [key[0] for key in record.parents]
4064
self.target_repo.add_inventory_by_delta(
4065
basis_id, inv_delta, revision_id, parents)
4067
4075
# It's not a delta, so it must be a fulltext in the source
4068
4076
# serializer's format.
4069
4077
bytes = record.get_bytes_as('fulltext')
4212
4220
# No need to stream something we don't have
4222
if substream_kind == 'inventory-deltas':
4214
4224
if substream_kind == 'inventories':
4215
4225
# Some missing keys are genuinely ghosts, filter those out.
4216
4226
present = self.from_repository.inventories.get_parent_map(keys)
4278
4288
# convert on the target, so we need to put bytes-on-the-wire that can
4279
4289
# be converted. That means inventory deltas (if the remote is <1.18,
4280
4290
# RemoteStreamSink will fallback to VFS to insert the deltas).
4281
yield ('inventories',
4291
yield ('inventory-deltas',
4282
4292
self._stream_invs_as_deltas(revision_ids,
4283
4293
delta_versus_null=delta_versus_null))
4307
4317
inventory_cache = lru_cache.LRUCache(50)
4308
4318
null_inventory = from_repo.revision_tree(
4309
4319
_mod_revision.NULL_REVISION).inventory
4320
serializer = inventory_delta.InventoryDeltaSerializer()
4321
serializer.require_flags(*flags)
4310
4322
for inv in inventories:
4311
4323
key = (inv.revision_id,)
4312
4324
parent_keys = parent_map.get(key, ())
4339
4351
delta = inv._make_delta(null_inventory)
4340
4352
invs_sent_so_far.add(inv.revision_id)
4341
4353
inventory_cache[inv.revision_id] = inv
4342
yield versionedfile.InventoryDeltaContentFactory(
4343
key, parent_keys, None, delta, basis_id, flags, from_repo)
4354
delta_serialized = ''.join(
4355
serializer.delta_to_lines(basis_id, key[-1], delta))
4356
yield versionedfile.FulltextContentFactory(
4357
key, parent_keys, None, delta_serialized)
4346
4360
def _iter_for_revno(repo, partial_history_cache, stop_index=None,