~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/reconcile.py

Merge up bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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.
70
73
        """
71
74
        self.pb = ui.ui_factory.nested_progress_bar()
72
75
        try:
76
79
 
77
80
    def _reconcile(self):
78
81
        """Helper function for performing reconciliation."""
 
82
        self._reconcile_branch()
 
83
        self._reconcile_repository()
 
84
 
 
85
    def _reconcile_branch(self):
 
86
        try:
 
87
            self.branch = self.bzrdir.open_branch()
 
88
        except errors.NotBranchError:
 
89
            # Nothing to check here
 
90
            self.fixed_branch_history = None
 
91
            return
 
92
        self.pb.note('Reconciling branch %s',
 
93
                     self.branch.base)
 
94
        branch_reconciler = self.branch.reconcile(thorough=True)
 
95
        self.fixed_branch_history = branch_reconciler.fixed_history
 
96
 
 
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.')
93
112
 
94
113
 
 
114
class BranchReconciler(object):
 
115
    """Reconciler that works on a branch."""
 
116
 
 
117
    def __init__(self, a_branch, thorough=False):
 
118
        self.fixed_history = None
 
119
        self.thorough = thorough
 
120
        self.branch = a_branch
 
121
 
 
122
    def reconcile(self):
 
123
        self.branch.lock_write()
 
124
        try:
 
125
            self.pb = ui.ui_factory.nested_progress_bar()
 
126
            try:
 
127
                self._reconcile_steps()
 
128
            finally:
 
129
                self.pb.finished()
 
130
        finally:
 
131
            self.branch.unlock()
 
132
 
 
133
    def _reconcile_steps(self):
 
134
        self._reconcile_revision_history()
 
135
 
 
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(
 
140
                                last_revision_id))
 
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,
 
147
            # though.
 
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),
 
151
                                               last_revision_id)
 
152
        else:
 
153
            self.fixed_history = False
 
154
            self.pb.note('revision_history ok.')
 
155
 
 
156
 
95
157
class RepoReconciler(object):
96
158
    """Reconciler that reconciles a repository.
97
159
 
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
 
249
            if unavailable:
 
250
                raise AssertionError('unavailable parents: %r'
 
251
                    % unavailable)
188
252
            # this entry has all the non ghost parents in the inventory
189
253
            # file already.
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
205
269
        # self.pending
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
225
289
        parents = []
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
 
407
            if unavailable:
 
408
                raise AssertionError(
 
409
                    'unavailable parents: %r' % (unavailable,))
344
410
            # this entry has all the non ghost parents in the inventory
345
411
            # file already.
346
412
            self._reweave_step('adding inventories')
350
416
 
351
417
        # if this worked, the set of new_inventory_vf.names should equal
352
418
        # self.pending
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)