42
45
class Reconciler(object):
43
"""Reconcilers are used to reconcile existing data.
45
Currently this is limited to a single repository, and consists
46
of an inventory reweave with revision cross-checks.
46
"""Reconcilers are used to reconcile existing data."""
49
48
def __init__(self, dir):
61
60
self.pb = ui.ui_factory.progress_bar()
62
61
self.repo = self.bzrdir.find_repository()
62
self.pb.note('Reconciling repository %s',
63
self.repo.bzrdir.root_transport.base)
64
repo_reconciler = RepoReconciler(self.repo)
65
repo_reconciler.reconcile()
66
self.inconsistent_parents = repo_reconciler.inconsistent_parents
67
self.garbage_inventories = repo_reconciler.garbage_inventories
68
self.pb.note('Reconciliation complete.')
71
class RepoReconciler(object):
72
"""Reconciler that reconciles a repository.
74
Currently this consists of an inventory reweave with revision cross-checks.
77
def __init__(self, repo):
81
"""Perform reconciliation.
83
After reconciliation the following attributes document found issues:
84
inconsistent_parents: The number of revisions in the repository whose
85
ancestry was being reported incorrectly.
86
garbage_inventories: The number of inventory objects without revisions
87
that were garbage collected.
89
self.pb = ui.ui_factory.progress_bar()
63
90
self.repo.lock_write()
65
self.pb.note('Reconciling repository %s',
66
self.repo.bzrdir.root_transport.base)
67
92
self._reweave_inventory()
70
self.pb.note('Reconciliation complete.')
72
96
def _reweave_inventory(self):
73
97
"""Regenerate the inventory weave for the repository from scratch."""
137
161
assert rev.revision_id == rev_id
139
163
for parent in rev.parent_ids:
140
if parent in self.inventory:
164
if self._parent_is_available(parent):
141
165
parents.append(parent)
143
167
mutter('found ghost %s', parent)
145
169
if set(self.inventory.parent_names(rev_id)) != set(parents):
146
170
self.inconsistent_parents += 1
172
def _parent_is_available(self, parent):
173
"""True if parent is a fully available revision
175
A fully available revision has a inventory and a revision object in the
178
return (parent in self._rev_graph or
179
(parent in self.inventory and self.repo.has_revision(parent)))
148
181
def _reweave_step(self, message):
149
182
"""Mark a single step of regeneration complete."""
150
183
self.pb.update(message, self.count, self.total)