67
67
ancestry was being reported incorrectly.
68
68
garbage_inventories: The number of inventory objects without revisions
69
69
that were garbage collected.
70
fixed_branch_history: None if there was no branch, False if the branch
71
history was correct, True if the branch history
72
needed to be re-normalized.
71
74
self.pb = ui.ui_factory.nested_progress_bar()
77
80
def _reconcile(self):
78
81
"""Helper function for performing reconciliation."""
82
self._reconcile_branch()
83
self._reconcile_repository()
85
def _reconcile_branch(self):
87
self.branch = self.bzrdir.open_branch()
88
except errors.NotBranchError:
89
# Nothing to check here
90
self.fixed_branch_history = None
92
self.pb.note('Reconciling branch %s',
94
branch_reconciler = self.branch.reconcile(thorough=True)
95
self.fixed_branch_history = branch_reconciler.fixed_history
97
def _reconcile_repository(self):
79
98
self.repo = self.bzrdir.find_repository()
80
99
self.pb.note('Reconciling repository %s',
81
100
self.repo.bzrdir.root_transport.base)
92
111
self.pb.note('Reconciliation complete.')
114
class BranchReconciler(object):
115
"""Reconciler that works on a branch."""
117
def __init__(self, a_branch, thorough=False):
118
self.fixed_history = None
119
self.thorough = thorough
120
self.branch = a_branch
123
self.branch.lock_write()
125
self.pb = ui.ui_factory.nested_progress_bar()
127
self._reconcile_steps()
133
def _reconcile_steps(self):
134
self._reconcile_revision_history()
136
def _reconcile_revision_history(self):
137
repo = self.branch.repository
138
last_revno, last_revision_id = self.branch.last_revision_info()
139
real_history = list(repo.iter_reverse_revision_history(
141
real_history.reverse()
142
if last_revno != len(real_history):
143
self.fixed_history = True
144
# Technically for Branch5 formats, it is more efficient to use
145
# set_revision_history, as this will regenerate it again.
146
# Not really worth a whole BranchReconciler class just for this,
148
self.pb.note('Fixing last revision info %s => %s',
149
last_revno, len(real_history))
150
self.branch.set_last_revision_info(len(real_history),
153
self.fixed_history = False
154
self.pb.note('revision_history ok.')
95
157
class RepoReconciler(object):
96
158
"""Reconciler that reconciles a repository.
184
246
parents = self._rev_graph[rev_id]
185
247
# double check this really is in topological order.
186
248
unavailable = [p for p in parents if p not in new_inventory_vf]
187
assert len(unavailable) == 0
250
raise AssertionError('unavailable parents: %r'
188
252
# this entry has all the non ghost parents in the inventory
190
254
self._reweave_step('adding inventories')
203
267
new_inventory_vf._save()
204
268
# if this worked, the set of new_inventory_vf.names should equal
206
assert set(new_inventory_vf.versions()) == self.pending
270
if not (set(new_inventory_vf.versions()) == self.pending):
271
raise AssertionError()
207
272
self.pb.update('Writing weave')
208
273
self.repo.control_weaves.copy(new_inventory_vf, 'inventory', self.repo.get_transaction())
209
274
self.repo.control_weaves.delete('inventory.new', self.repo.get_transaction())
221
286
# analyse revision id rev_id and put it in the stack.
222
287
self._reweave_step('loading revisions')
223
288
rev = self.repo.get_revision_reconcile(rev_id)
224
assert rev.revision_id == rev_id
226
290
for parent in rev.parent_ids:
227
291
if self._parent_is_available(parent):
340
404
# double check this really is in topological order, ignoring existing ghosts.
341
405
unavailable = [p for p in parents if p not in new_inventory_vf and
342
406
p in self.revisions]
343
assert len(unavailable) == 0
408
raise AssertionError(
409
'unavailable parents: %r' % (unavailable,))
344
410
# this entry has all the non ghost parents in the inventory
346
412
self._reweave_step('adding inventories')
351
417
# if this worked, the set of new_inventory_vf.names should equal
353
assert set(new_inventory_vf.versions()) == set(self.revisions.versions())
419
if not(set(new_inventory_vf.versions()) == set(self.revisions.versions())):
420
raise AssertionError()
354
421
self.pb.update('Writing weave')
355
422
self.repo.control_weaves.copy(new_inventory_vf, 'inventory', self.transaction)
356
423
self.repo.control_weaves.delete('inventory.new', self.transaction)