~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/check.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-10-05 21:15:13 UTC
  • mfrom: (5448.3.5 374700-Add-gnu-lsh-support)
  • Revision ID: pqm@pqm.ubuntu.com-20101005211513-whouyj5t7oo92gmq
(gz) Add support for GNU lsh as a secure shell client (Matthew Gordon)

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
so that when the dependent object is checked, matches can be pulled out and
40
40
evaluated in-line rather than re-reading the same data many times.
41
41
check_refs are tuples (kind, value). Currently defined kinds are:
42
 
 
43
42
* 'trees', where value is a revid and the looked up objects are revision trees.
44
43
* 'lefthand-distance', where value is a revid and the looked up objects are the
45
44
  distance along the lefthand path to NULL for that revid.
47
46
  indicating that the revision was found/not found.
48
47
"""
49
48
 
50
 
from __future__ import absolute_import
51
 
 
52
 
from bzrlib import (
53
 
    errors,
54
 
    ui,
55
 
    )
 
49
from bzrlib import errors
56
50
from bzrlib.branch import Branch
57
 
from bzrlib.controldir import ControlDir
 
51
from bzrlib.bzrdir import BzrDir
58
52
from bzrlib.revision import NULL_REVISION
 
53
from bzrlib.symbol_versioning import deprecated_function, deprecated_in
59
54
from bzrlib.trace import note
 
55
import bzrlib.ui
60
56
from bzrlib.workingtree import WorkingTree
61
 
from bzrlib.i18n import gettext
62
57
 
63
58
class Check(object):
64
59
    """Check a repository"""
65
60
 
66
 
    def __init__(self, repository, check_repo=True):
67
 
        self.repository = repository
68
 
 
69
 
    def report_results(self, verbose):
70
 
        raise NotImplementedError(self.report_results)
71
 
 
72
 
 
73
 
class VersionedFileCheck(Check):
74
 
    """Check a versioned file repository"""
75
 
 
76
61
    # The Check object interacts with InventoryEntry.check, etc.
77
62
 
78
63
    def __init__(self, repository, check_repo=True):
103
88
        if callback_refs is None:
104
89
            callback_refs = {}
105
90
        self.repository.lock_read()
106
 
        self.progress = ui.ui_factory.nested_progress_bar()
 
91
        self.progress = bzrlib.ui.ui_factory.nested_progress_bar()
107
92
        try:
108
 
            self.progress.update(gettext('check'), 0, 4)
 
93
            self.progress.update('check', 0, 4)
109
94
            if self.check_repo:
110
 
                self.progress.update(gettext('checking revisions'), 0)
 
95
                self.progress.update('checking revisions', 0)
111
96
                self.check_revisions()
112
 
                self.progress.update(gettext('checking commit contents'), 1)
 
97
                self.progress.update('checking commit contents', 1)
113
98
                self.repository._check_inventories(self)
114
 
                self.progress.update(gettext('checking file graphs'), 2)
 
99
                self.progress.update('checking file graphs', 2)
115
100
                # check_weaves is done after the revision scan so that
116
101
                # revision index is known to be valid.
117
102
                self.check_weaves()
118
 
            self.progress.update(gettext('checking branches and trees'), 3)
 
103
            self.progress.update('checking branches and trees', 3)
119
104
            if callback_refs:
120
105
                repo = self.repository
121
106
                # calculate all refs, and callback the objects requesting them.
185
170
        # - we can fill out existence flags at this point
186
171
        # - we can read the revision inventory sha at this point
187
172
        # - we can check properties and serialisers etc.
188
 
        if not self.repository._format.revision_graph_can_have_wrong_parents:
 
173
        if not self.repository.revision_graph_can_have_wrong_parents():
189
174
            # The check against the index isn't needed.
190
175
            self.revs_with_bad_parents_in_index = None
191
176
            for thing in revision_iterator:
202
187
            result.report_results(verbose)
203
188
 
204
189
    def _report_repo_results(self, verbose):
205
 
        note(gettext('checked repository {0} format {1}').format(
 
190
        note('checked repository %s format %s',
206
191
            self.repository.user_url,
207
 
            self.repository._format))
208
 
        note(gettext('%6d revisions'), self.checked_rev_cnt)
209
 
        note(gettext('%6d file-ids'), len(self.checked_weaves))
 
192
            self.repository._format)
 
193
        note('%6d revisions', self.checked_rev_cnt)
 
194
        note('%6d file-ids', len(self.checked_weaves))
210
195
        if verbose:
211
 
            note(gettext('%6d unreferenced text versions'),
 
196
            note('%6d unreferenced text versions',
212
197
                len(self.unreferenced_versions))
213
198
        if verbose and len(self.unreferenced_versions):
214
199
                for file_id, revision_id in self.unreferenced_versions:
215
 
                    note(gettext('unreferenced version: {{{0}}} in {1}').format(revision_id,
216
 
                        file_id))
 
200
                    note('unreferenced version: {%s} in %s', revision_id,
 
201
                        file_id)
217
202
        if self.missing_inventory_sha_cnt:
218
 
            note(gettext('%6d revisions are missing inventory_sha1'),
 
203
            note('%6d revisions are missing inventory_sha1',
219
204
                 self.missing_inventory_sha_cnt)
220
205
        if self.missing_revision_cnt:
221
 
            note(gettext('%6d revisions are mentioned but not present'),
 
206
            note('%6d revisions are mentioned but not present',
222
207
                 self.missing_revision_cnt)
223
208
        if len(self.ghosts):
224
 
            note(gettext('%6d ghost revisions'), len(self.ghosts))
 
209
            note('%6d ghost revisions', len(self.ghosts))
225
210
            if verbose:
226
211
                for ghost in self.ghosts:
227
212
                    note('      %s', ghost)
228
213
        if len(self.missing_parent_links):
229
 
            note(gettext('%6d revisions missing parents in ancestry'),
 
214
            note('%6d revisions missing parents in ancestry',
230
215
                 len(self.missing_parent_links))
231
216
            if verbose:
232
217
                for link, linkers in self.missing_parent_links.items():
233
 
                    note(gettext('      %s should be in the ancestry for:'), link)
 
218
                    note('      %s should be in the ancestry for:', link)
234
219
                    for linker in linkers:
235
220
                        note('       * %s', linker)
236
221
        if len(self.inconsistent_parents):
237
 
            note(gettext('%6d inconsistent parents'), len(self.inconsistent_parents))
 
222
            note('%6d inconsistent parents', len(self.inconsistent_parents))
238
223
            if verbose:
239
224
                for info in self.inconsistent_parents:
240
225
                    revision_id, file_id, found_parents, correct_parents = info
241
 
                    note(gettext('      * {0} version {1} has parents {2!r} '
242
 
                         'but should have {3!r}').format(
243
 
                         file_id, revision_id, found_parents,
 
226
                    note('      * %s version %s has parents %r '
 
227
                         'but should have %r'
 
228
                         % (file_id, revision_id, found_parents,
244
229
                             correct_parents))
245
230
        if self.revs_with_bad_parents_in_index:
246
 
            note(gettext(
247
 
                 '%6d revisions have incorrect parents in the revision index'),
 
231
            note('%6d revisions have incorrect parents in the revision index',
248
232
                 len(self.revs_with_bad_parents_in_index))
249
233
            if verbose:
250
234
                for item in self.revs_with_bad_parents_in_index:
251
235
                    revision_id, index_parents, actual_parents = item
252
 
                    note(gettext(
253
 
                        '       {0} has wrong parents in index: '
254
 
                        '{1!r} should be {2!r}').format(
255
 
                        revision_id, index_parents, actual_parents))
 
236
                    note(
 
237
                        '       %s has wrong parents in index: '
 
238
                        '%r should be %r',
 
239
                        revision_id, index_parents, actual_parents)
256
240
        for item in self._report_items:
257
241
            note(item)
258
242
 
263
247
        :param rev: A revision or None to indicate a missing revision.
264
248
        """
265
249
        if rev.revision_id != rev_id:
266
 
            self._report_items.append(gettext(
267
 
                'Mismatched internal revid {{{0}}} and index revid {{{1}}}').format(
 
250
            self._report_items.append(
 
251
                'Mismatched internal revid {%s} and index revid {%s}' % (
268
252
                rev.revision_id, rev_id))
269
253
            rev_id = rev.revision_id
270
254
        # Check this revision tree etc, and count as seen when we encounter a
293
277
        existing = self.pending_keys.get(key)
294
278
        if existing:
295
279
            if sha1 != existing[1]:
296
 
                self._report_items.append(gettext('Multiple expected sha1s for {0}. {{{1}}}'
297
 
                    ' expects {{{2}}}, {{{3}}} expects {{{4}}}').format(
 
280
                self._report_items.append('Multiple expected sha1s for %s. {%s}'
 
281
                    ' expects {%s}, {%s} expects {%s}', (
298
282
                    key, referer, sha1, existing[1], existing[0]))
299
283
        else:
300
284
            self.pending_keys[key] = (kind, sha1, referer)
303
287
        """Check all the weaves we can get our hands on.
304
288
        """
305
289
        weave_ids = []
306
 
        storebar = ui.ui_factory.nested_progress_bar()
 
290
        storebar = bzrlib.ui.ui_factory.nested_progress_bar()
307
291
        try:
308
292
            self._check_weaves(storebar)
309
293
        finally:
344
328
            self.text_key_references[key] = True
345
329
 
346
330
 
 
331
@deprecated_function(deprecated_in((1,6,0)))
 
332
def check(branch, verbose):
 
333
    """Run consistency checks on a branch.
 
334
 
 
335
    Results are reported through logging.
 
336
 
 
337
    Deprecated in 1.6.  Please use check_dwim instead.
 
338
 
 
339
    :raise BzrCheckError: if there's a consistency error.
 
340
    """
 
341
    check_branch(branch, verbose)
 
342
 
 
343
 
 
344
@deprecated_function(deprecated_in((1,16,0)))
 
345
def check_branch(branch, verbose):
 
346
    """Run consistency checks on a branch.
 
347
 
 
348
    Results are reported through logging.
 
349
 
 
350
    :raise BzrCheckError: if there's a consistency error.
 
351
    """
 
352
    branch.lock_read()
 
353
    try:
 
354
        needed_refs = {}
 
355
        for ref in branch._get_check_refs():
 
356
            needed_refs.setdefault(ref, []).append(branch)
 
357
        result = branch.repository.check([branch.last_revision()], needed_refs)
 
358
        branch_result = result.other_results[0]
 
359
    finally:
 
360
        branch.unlock()
 
361
    branch_result.report_results(verbose)
 
362
 
 
363
 
347
364
def scan_branch(branch, needed_refs, to_unlock):
348
365
    """Scan a branch for refs.
349
366
 
351
368
    :param needed_refs: Refs we are accumulating.
352
369
    :param to_unlock: The unlock list accumulating.
353
370
    """
354
 
    note(gettext("Checking branch at '%s'.") % (branch.base,))
 
371
    note("Checking branch at '%s'." % (branch.base,))
355
372
    branch.lock_read()
356
373
    to_unlock.append(branch)
357
374
    branch_refs = branch._get_check_refs()
371
388
    """
372
389
    if base_tree is not None and tree.basedir == base_tree.basedir:
373
390
        return
374
 
    note(gettext("Checking working tree at '%s'.") % (tree.basedir,))
 
391
    note("Checking working tree at '%s'." % (tree.basedir,))
375
392
    tree.lock_read()
376
393
    to_unlock.append(tree)
377
394
    tree_refs = tree._get_check_refs()
388
405
    """
389
406
    try:
390
407
        base_tree, branch, repo, relpath = \
391
 
                        ControlDir.open_containing_tree_branch_or_repository(path)
 
408
                        BzrDir.open_containing_tree_branch_or_repository(path)
392
409
    except errors.NotBranchError:
393
410
        base_tree = branch = repo = None
394
411
 
424
441
                    if do_branch:
425
442
                        scan_branch(branch, needed_refs, to_unlock)
426
443
            if do_branch and not branches:
427
 
                note(gettext("No branch found at specified location."))
 
444
                note("No branch found at specified location.")
428
445
            if do_tree and base_tree is None and not saw_tree:
429
 
                note(gettext("No working tree found at specified location."))
 
446
                note("No working tree found at specified location.")
430
447
            if do_repo or do_branch or do_tree:
431
448
                if do_repo:
432
 
                    note(gettext("Checking repository at '%s'.")
 
449
                    note("Checking repository at '%s'."
433
450
                         % (repo.user_url,))
434
451
                result = repo.check(None, callback_refs=needed_refs,
435
452
                    check_repo=do_repo)
436
453
                result.report_results(verbose)
437
454
        else:
438
455
            if do_tree:
439
 
                note(gettext("No working tree found at specified location."))
 
456
                note("No working tree found at specified location.")
440
457
            if do_branch:
441
 
                note(gettext("No branch found at specified location."))
 
458
                note("No branch found at specified location.")
442
459
            if do_repo:
443
 
                note(gettext("No repository found at specified location."))
 
460
                note("No repository found at specified location.")
444
461
    finally:
445
462
        for thing in to_unlock:
446
463
            thing.unlock()