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
for num, file_id in enumerate(self.repo.weave_store):
382
vf_checker = self.repo._get_versioned_file_checker()
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:
386
387
self.pb.update('Fixing text parents', num,
387
388
len(self.repo.weave_store))
388
389
vf = self.repo.weave_store.get_weave(file_id, transaction)
389
vf_checker = self.repo.get_versioned_file_checker(
390
vf.versions(), revision_versions)
391
versions_with_bad_parents, dangling_file_versions = \
390
versions_with_bad_parents, unused_versions = \
392
391
vf_checker.check_file_version_parents(vf, file_id)
393
392
if (len(versions_with_bad_parents) == 0 and
394
len(dangling_file_versions) == 0):
393
len(unused_versions) == 0):
396
395
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
396
self._fix_text_parent(file_id, vf, versions_with_bad_parents,
419
397
full_text_versions, unused_versions)
429
407
self.transaction)
431
409
for version in vf.versions():
432
if version in versions_with_bad_parents:
410
if version in unused_versions:
412
elif version in versions_with_bad_parents:
433
413
parents = versions_with_bad_parents[version][1]
435
415
parents = vf.get_parents(version)
436
416
new_parents[version] = parents
417
if not len(new_parents):
418
# No used versions, remove the VF.
419
self.repo.weave_store.delete(file_id, self.transaction)
437
421
for version in TopoSorter(new_parents.items()).iter_topo_order():
438
if version in unused_versions:
440
422
lines = vf.get_lines(version)
441
423
parents = new_parents[version]
442
424
if parents and (parents[0] in full_text_versions):