~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/check.py

(vila) Make all transport put_bytes() raises TypeError when given unicode
 strings rather than bytes (Vincent Ladeuil)

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