376
376
parent lists, and replaces the versionedfile with a corrected version.
378
378
transaction = self.repo.get_transaction()
379
revision_versions = repository._RevisionTextVersionCache(self.repo)
380
379
versions = self.revisions.versions()
381
380
mutter('Prepopulating revision text cache with %d revisions',
383
revision_versions.prepopulate_revs(versions)
384
used_file_versions = revision_versions.used_file_versions()
385
382
vf_checker = self.repo.get_versioned_file_checker()
386
for num, file_id in enumerate(self.repo.weave_store):
383
# List all weaves before altering, to avoid race conditions when we
384
# delete unused weaves.
385
weaves = list(enumerate(self.repo.weave_store))
386
for num, file_id in weaves:
387
387
self.pb.update('Fixing text parents', num,
388
388
len(self.repo.weave_store))
389
389
vf = self.repo.weave_store.get_weave(file_id, transaction)
390
versions_with_bad_parents, dangling_file_versions = \
390
versions_with_bad_parents, unused_versions = \
391
391
vf_checker.check_file_version_parents(vf, file_id,
392
vf.versions(), revision_versions)
393
393
if (len(versions_with_bad_parents) == 0 and
394
len(dangling_file_versions) == 0):
394
len(unused_versions) == 0):
396
396
full_text_versions = set()
397
unused_versions = set()
398
for dangling_version in dangling_file_versions:
399
version = dangling_version[1]
400
if dangling_version in used_file_versions:
401
# This version *is* used by some revision, even though it
402
# isn't used by its own revision! We make sure any
403
# revision referencing it is stored as a fulltext
404
# This avoids bug 155730: it means that clients looking at
405
# inventories to determine the versions to fetch will not
406
# miss a required version. (So clients can assume that if
407
# they have a complete revision graph, and fetch all file
408
# versions named by those revisions inventories, then they
409
# will not have any missing parents for 'delta' knit
411
# XXX: A better, but more difficult and slower fix would be
412
# to rewrite the inventories referencing this version.
413
full_text_versions.add(version)
415
# This version is totally unreferenced. It should be
417
unused_versions.add(version)
418
397
self._fix_text_parent(file_id, vf, versions_with_bad_parents,
419
398
full_text_versions, unused_versions)
429
408
self.transaction)
431
410
for version in vf.versions():
432
if version in versions_with_bad_parents:
411
if version in unused_versions:
413
elif version in versions_with_bad_parents:
433
414
parents = versions_with_bad_parents[version][1]
435
416
parents = vf.get_parents(version)
436
417
new_parents[version] = parents
418
if not len(new_parents):
419
# No used versions, remove the VF.
420
self.repo.weave_store.delete(file_id, self.transaction)
437
422
for version in TopoSorter(new_parents.items()).iter_topo_order():
438
if version in unused_versions:
440
423
lines = vf.get_lines(version)
441
424
parents = new_parents[version]
442
425
if parents and (parents[0] in full_text_versions):