~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/reconcile.py

  • Committer: Robert Collins
  • Date: 2006-02-28 01:13:01 UTC
  • mto: (1587.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 1588.
  • Revision ID: robertc@robertcollins.net-20060228011301-df7ce3b80dfb37ba
Enforce repository consistency during 'fetch' operations.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
"""Reconcilers are able to fix some potential data errors in a branch."""
18
18
 
19
19
 
 
20
__all__ = ['reconcile', 'Reconciler', 'RepoReconciler']
 
21
 
 
22
 
20
23
import bzrlib.branch
21
24
import bzrlib.errors as errors
22
25
import bzrlib.progress
40
43
 
41
44
 
42
45
class Reconciler(object):
43
 
    """Reconcilers are used to reconcile existing data.
44
 
 
45
 
    Currently this is limited to a single repository, and consists
46
 
    of an inventory reweave with revision cross-checks.
47
 
    """
 
46
    """Reconcilers are used to reconcile existing data."""
48
47
 
49
48
    def __init__(self, dir):
50
49
        self.bzrdir = dir
60
59
        """
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.')
 
69
 
 
70
 
 
71
class RepoReconciler(object):
 
72
    """Reconciler that reconciles a repository.
 
73
 
 
74
    Currently this consists of an inventory reweave with revision cross-checks.
 
75
    """
 
76
 
 
77
    def __init__(self, repo):
 
78
        self.repo = repo
 
79
 
 
80
    def reconcile(self):
 
81
        """Perform reconciliation.
 
82
        
 
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.
 
88
        """
 
89
        self.pb = ui.ui_factory.progress_bar()
63
90
        self.repo.lock_write()
64
91
        try:
65
 
            self.pb.note('Reconciling repository %s',
66
 
                         self.repo.bzrdir.root_transport.base)
67
92
            self._reweave_inventory()
68
93
        finally:
69
94
            self.repo.unlock()
70
 
        self.pb.note('Reconciliation complete.')
71
95
 
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
138
162
        parents = []
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)
142
166
            else:
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
147
171
 
 
172
    def _parent_is_available(self, parent):
 
173
        """True if parent is a fully available revision
 
174
 
 
175
        A fully available revision has a inventory and a revision object in the
 
176
        repository.
 
177
        """
 
178
        return (parent in self._rev_graph or 
 
179
                (parent in self.inventory and self.repo.has_revision(parent)))
 
180
 
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)