54
53
from bzrlib.branch import Branch
55
54
from bzrlib.bzrdir import BzrDir
56
55
from bzrlib.revision import NULL_REVISION
56
from bzrlib.symbol_versioning import deprecated_function, deprecated_in
57
57
from bzrlib.trace import note
58
58
from bzrlib.workingtree import WorkingTree
59
from bzrlib.i18n import gettext
61
60
class Check(object):
62
61
"""Check a repository"""
64
def __init__(self, repository, check_repo=True):
65
self.repository = repository
67
def report_results(self, verbose):
68
raise NotImplementedError(self.report_results)
71
class VersionedFileCheck(Check):
72
"""Check a versioned file repository"""
74
63
# The Check object interacts with InventoryEntry.check, etc.
76
65
def __init__(self, repository, check_repo=True):
103
92
self.repository.lock_read()
104
93
self.progress = ui.ui_factory.nested_progress_bar()
106
self.progress.update(gettext('check'), 0, 4)
95
self.progress.update('check', 0, 4)
107
96
if self.check_repo:
108
self.progress.update(gettext('checking revisions'), 0)
97
self.progress.update('checking revisions', 0)
109
98
self.check_revisions()
110
self.progress.update(gettext('checking commit contents'), 1)
99
self.progress.update('checking commit contents', 1)
111
100
self.repository._check_inventories(self)
112
self.progress.update(gettext('checking file graphs'), 2)
101
self.progress.update('checking file graphs', 2)
113
102
# check_weaves is done after the revision scan so that
114
103
# revision index is known to be valid.
115
104
self.check_weaves()
116
self.progress.update(gettext('checking branches and trees'), 3)
105
self.progress.update('checking branches and trees', 3)
117
106
if callback_refs:
118
107
repo = self.repository
119
108
# calculate all refs, and callback the objects requesting them.
200
189
result.report_results(verbose)
202
191
def _report_repo_results(self, verbose):
203
note(gettext('checked repository {0} format {1}').format(
192
note('checked repository %s format %s',
204
193
self.repository.user_url,
205
self.repository._format))
206
note(gettext('%6d revisions'), self.checked_rev_cnt)
207
note(gettext('%6d file-ids'), len(self.checked_weaves))
194
self.repository._format)
195
note('%6d revisions', self.checked_rev_cnt)
196
note('%6d file-ids', len(self.checked_weaves))
209
note(gettext('%6d unreferenced text versions'),
198
note('%6d unreferenced text versions',
210
199
len(self.unreferenced_versions))
211
200
if verbose and len(self.unreferenced_versions):
212
201
for file_id, revision_id in self.unreferenced_versions:
213
note(gettext('unreferenced version: {{{0}}} in {1}').format(revision_id,
202
note('unreferenced version: {%s} in %s', revision_id,
215
204
if self.missing_inventory_sha_cnt:
216
note(gettext('%6d revisions are missing inventory_sha1'),
205
note('%6d revisions are missing inventory_sha1',
217
206
self.missing_inventory_sha_cnt)
218
207
if self.missing_revision_cnt:
219
note(gettext('%6d revisions are mentioned but not present'),
208
note('%6d revisions are mentioned but not present',
220
209
self.missing_revision_cnt)
221
210
if len(self.ghosts):
222
note(gettext('%6d ghost revisions'), len(self.ghosts))
211
note('%6d ghost revisions', len(self.ghosts))
224
213
for ghost in self.ghosts:
225
214
note(' %s', ghost)
226
215
if len(self.missing_parent_links):
227
note(gettext('%6d revisions missing parents in ancestry'),
216
note('%6d revisions missing parents in ancestry',
228
217
len(self.missing_parent_links))
230
219
for link, linkers in self.missing_parent_links.items():
231
note(gettext(' %s should be in the ancestry for:'), link)
220
note(' %s should be in the ancestry for:', link)
232
221
for linker in linkers:
233
222
note(' * %s', linker)
234
223
if len(self.inconsistent_parents):
235
note(gettext('%6d inconsistent parents'), len(self.inconsistent_parents))
224
note('%6d inconsistent parents', len(self.inconsistent_parents))
237
226
for info in self.inconsistent_parents:
238
227
revision_id, file_id, found_parents, correct_parents = info
239
note(gettext(' * {0} version {1} has parents {2!r} '
240
'but should have {3!r}').format(
241
file_id, revision_id, found_parents,
228
note(' * %s version %s has parents %r '
230
% (file_id, revision_id, found_parents,
242
231
correct_parents))
243
232
if self.revs_with_bad_parents_in_index:
245
'%6d revisions have incorrect parents in the revision index'),
233
note('%6d revisions have incorrect parents in the revision index',
246
234
len(self.revs_with_bad_parents_in_index))
248
236
for item in self.revs_with_bad_parents_in_index:
249
237
revision_id, index_parents, actual_parents = item
251
' {0} has wrong parents in index: '
252
'{1!r} should be {2!r}').format(
253
revision_id, index_parents, actual_parents))
239
' %s has wrong parents in index: '
241
revision_id, index_parents, actual_parents)
254
242
for item in self._report_items:
423
411
scan_branch(branch, needed_refs, to_unlock)
424
412
if do_branch and not branches:
425
note(gettext("No branch found at specified location."))
413
note("No branch found at specified location.")
426
414
if do_tree and base_tree is None and not saw_tree:
427
note(gettext("No working tree found at specified location."))
415
note("No working tree found at specified location.")
428
416
if do_repo or do_branch or do_tree:
430
note(gettext("Checking repository at '%s'.")
418
note("Checking repository at '%s'."
431
419
% (repo.user_url,))
432
420
result = repo.check(None, callback_refs=needed_refs,
433
421
check_repo=do_repo)
434
422
result.report_results(verbose)
437
note(gettext("No working tree found at specified location."))
425
note("No working tree found at specified location.")
439
note(gettext("No branch found at specified location."))
427
note("No branch found at specified location.")
441
note(gettext("No repository found at specified location."))
429
note("No repository found at specified location.")
443
431
for thing in to_unlock: