168
171
if knit_kind == "file":
169
172
self._fetch_weave_text(file_id, revisions)
170
173
elif knit_kind == "inventory":
172
# Once we've processed all the files, then we generate the root
173
# texts (if necessary), then we process the inventory. It's a
174
# bit distasteful to have knit_kind == "inventory" mean this,
175
# perhaps it should happen on the first non-"file" knit, in case
176
# it's not always inventory?
174
# Before we process the inventory we generate the root
175
# texts (if necessary) so that the inventories references
177
177
self._generate_root_texts(revs)
178
# NB: This currently reopens the inventory weave in source;
179
# using a full get_data_stream instead would avoid this.
178
180
self._fetch_inventory_weave(revs, pb)
179
181
elif knit_kind == "signatures":
180
182
# Nothing to do here; this will be taken care of when
214
216
self.to_repository.get_transaction())
215
217
from_weave = self.from_weaves.get_weave(file_id,
216
218
self.from_repository.get_transaction())
217
# we fetch all the texts, because texts do
218
# not reference anything, and its cheap enough
219
to_weave.join(from_weave, version_ids=required_versions)
220
# we don't need *all* of this data anymore, but we dont know
221
# what we do. This cache clearing will result in a new read
222
# of the knit data when we do the checkout, but probably we
223
# want to emit the needed data on the fly rather than at the
225
# the from weave should know not to cache data being joined,
226
# but its ok to ask it to clear.
227
from_weave.clear_cache()
228
to_weave.clear_cache()
219
# Fetch all the texts.
220
to_weave.insert_record_stream(from_weave.get_record_stream(
221
required_versions, 'topological', False))
230
223
def _fetch_inventory_weave(self, revs, pb):
231
224
pb.update("fetch inventory", 0, 2)
306
301
from_sf = self.from_repository._revision_store.get_signature_file(
307
302
from_transaction)
308
to_sf.join(from_sf, version_ids=revs, ignore_missing=True)
303
# A missing signature is just skipped.
304
to_sf.insert_record_stream(filter_absent(from_sf.get_record_stream(revs,
305
'unordered', False)))
306
self._fetch_just_revision_texts(revs, from_transaction, to_transaction)
308
def _fetch_just_revision_texts(self, version_ids, from_transaction,
309
310
to_rf = self.to_repository._revision_store.get_revision_file(
311
312
from_rf = self.from_repository._revision_store.get_revision_file(
312
313
from_transaction)
313
to_rf.join(from_rf, version_ids=revs)
314
to_rf.insert_record_stream(from_rf.get_record_stream(version_ids,
315
'topological', False))
316
318
class Inter1and2Helper(object):
348
350
revs = revs[100:]
352
def _find_root_ids(self, revs, parent_map, graph):
354
planned_versions = {}
355
for tree in self.iter_rev_trees(revs):
356
revision_id = tree.inventory.root.revision
357
root_id = tree.get_root_id()
358
planned_versions.setdefault(root_id, []).append(revision_id)
359
revision_root[revision_id] = root_id
360
# Find out which parents we don't already know root ids for
362
for revision_parents in parent_map.itervalues():
363
parents.update(revision_parents)
364
parents.difference_update(revision_root.keys() + [NULL_REVISION])
365
# Limit to revisions present in the versionedfile
366
parents = graph.get_parent_map(parents).keys()
367
for tree in self.iter_rev_trees(parents):
368
root_id = tree.get_root_id()
369
revision_root[tree.get_revision_id()] = root_id
370
return revision_root, planned_versions
350
372
def generate_root_texts(self, revs):
351
373
"""Generate VersionedFiles for all root ids.
353
375
:param revs: the revisions to include
355
inventory_weave = self.source.get_inventory_weave()
358
377
to_store = self.target.weave_store
359
for tree in self.iter_rev_trees(revs):
360
revision_id = tree.inventory.root.revision
361
root_id = tree.get_root_id()
362
parents = inventory_weave.get_parents(revision_id)
363
if root_id not in versionedfile:
364
versionedfile[root_id] = to_store.get_weave_or_empty(root_id,
365
self.target.get_transaction())
366
_, _, parent_texts[root_id] = versionedfile[root_id].add_lines(
367
revision_id, parents, [], parent_texts)
378
graph = self.source.get_graph()
379
parent_map = graph.get_parent_map(revs)
380
revision_root, planned_versions = self._find_root_ids(
381
revs, parent_map, graph)
382
for root_id, versions in planned_versions.iteritems():
383
versionedfile = to_store.get_weave_or_empty(root_id,
384
self.target.get_transaction())
386
for revision_id in versions:
387
if revision_id in versionedfile:
389
parents = parent_map[revision_id]
390
# We drop revision parents with different file-ids, because
391
# a version cannot have a version with another file-id as its
393
# When a parent revision is a ghost, we guess that its root id
395
parents = tuple(p for p in parents if p != NULL_REVISION
396
and revision_root.get(p, root_id) == root_id)
397
result = versionedfile.add_lines_with_ghosts(
398
revision_id, parents, [], parent_texts)
399
parent_texts[revision_id] = result[2]
369
401
def regenerate_inventory(self, revs):
370
402
"""Generate a new inventory versionedfile in target, convertin data.