/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2052.3.2 by John Arbash Meinel
Change Copyright .. by Canonical to Copyright ... Canonical
1
# Copyright (C) 2005, 2006 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1 by mbp at sourcefrog
import from baz patch-364
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1 by mbp at sourcefrog
import from baz patch-364
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1 by mbp at sourcefrog
import from baz patch-364
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1 by mbp at sourcefrog
import from baz patch-364
16
1335 by Martin Pool
doc
17
# TODO: Check ancestries are correct for every revision: includes
18
# every committed so far, and in a reasonable order.
19
1347 by Martin Pool
- refactor check code into method object
20
# TODO: Also check non-mainline revisions mentioned as parents.
21
22
# TODO: Check for extra files in the control directory.
23
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
24
# TODO: Check revision, inventory and entry objects have all
1348 by Martin Pool
- more refactoring of check code
25
# required fields.
26
1185.16.101 by mbp at sourcefrog
todo
27
# TODO: Get every revision in the revision-store even if they're not
28
# referenced by history and make sure they're all valid.
1347 by Martin Pool
- refactor check code into method object
29
1616.1.5 by Martin Pool
Cleanup and document some check code
30
# TODO: Perhaps have a way to record errors other than by raising exceptions;
31
# would perhaps be enough to accumulate exception objects in a list without
32
# raising them.  If there's more than one exception it'd be good to see them
33
# all.
34
4332.3.2 by Robert Collins
Extract repository access in WorkingTree._check to be data driven, adding a new _get_check_refs method to support this.
35
"""Checking of bzr objects.
36
37
check_refs is a concept used for optimising check. Objects that depend on other
38
objects (e.g. tree on repository) can list the objects they would be requesting
39
so that when the dependent object is checked, matches can be pulled out and
40
evaluated in-line rather than re-reading the same data many times.
41
check_refs are tuples (kind, value). Currently defined kinds are:
4332.3.5 by Robert Collins
Add Branch._get_check_refs.
42
* 'trees', where value is a revid and the looked up objects are revision trees.
43
* 'lefthand-distance', where value is a revid and the looked up objects are the
44
  distance along the lefthand path to NULL for that revid.
45
* 'revision-existence', where value is a revid, and the result is True or False
46
  indicating that the revision was found/not found.
4332.3.2 by Robert Collins
Extract repository access in WorkingTree._check to be data driven, adding a new _get_check_refs method to support this.
47
"""
48
3015.3.8 by Daniel Watkins
Added _scan_for_branches.
49
from bzrlib import errors, osutils
2745.6.16 by Aaron Bentley
Update from review
50
from bzrlib import repository as _mod_repository
2745.6.47 by Andrew Bennetts
Move check_parents out of VersionedFile.
51
from bzrlib import revision
3015.3.2 by Daniel Watkins
Check.check now takes a path rather than a branch.
52
from bzrlib.branch import Branch
3015.3.40 by Daniel Watkins
Modified bzrlib.check.check_dwim to use bzrlib.bzrdir.BzrDir.open_containing_tree_branch_or_repository.
53
from bzrlib.bzrdir import BzrDir
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
54
from bzrlib.errors import BzrCheckError
3015.3.3 by Daniel Watkins
Added _check_repository.
55
from bzrlib.repository import Repository
3015.3.59 by Daniel Watkins
Further tweaks as requested on-list.
56
from bzrlib.symbol_versioning import deprecated_function, deprecated_in
3015.3.35 by Daniel Watkins
Reintroduced bzrlib.check.check() with a deprecation warning.
57
from bzrlib.trace import log_error, note
1104 by Martin Pool
- Add a simple UIFactory
58
import bzrlib.ui
3015.3.11 by Daniel Watkins
Move WT checking from builtins to check.
59
from bzrlib.workingtree import WorkingTree
1104 by Martin Pool
- Add a simple UIFactory
60
1347 by Martin Pool
- refactor check code into method object
61
class Check(object):
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
62
    """Check a repository"""
1449 by Robert Collins
teach check about ghosts
63
1616.1.5 by Martin Pool
Cleanup and document some check code
64
    # The Check object interacts with InventoryEntry.check, etc.
65
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
66
    def __init__(self, repository):
67
        self.repository = repository
1383 by Martin Pool
- untabify only
68
        self.checked_text_cnt = 0
69
        self.checked_rev_cnt = 0
1449 by Robert Collins
teach check about ghosts
70
        self.ghosts = []
1365 by Martin Pool
- try to avoid checking texts repeatedly
71
        self.repeated_text_cnt = 0
1449 by Robert Collins
teach check about ghosts
72
        self.missing_parent_links = {}
1348 by Martin Pool
- more refactoring of check code
73
        self.missing_inventory_sha_cnt = 0
74
        self.missing_revision_cnt = 0
1616.1.5 by Martin Pool
Cleanup and document some check code
75
        # maps (file-id, version) -> sha1; used by InventoryFile._check
1365 by Martin Pool
- try to avoid checking texts repeatedly
76
        self.checked_texts = {}
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
77
        self.checked_weaves = set()
2988.1.8 by Robert Collins
Change check and reconcile to use the new _generate_text_key_index rather
78
        self.unreferenced_versions = set()
2745.6.33 by Andrew Bennetts
Add VersionedFile.check_parents, and use it instead of find_bad_ancestors in reconcile.
79
        self.inconsistent_parents = []
4145.2.1 by Ian Clatworthy
faster check
80
        self.rich_roots = repository.supports_rich_root()
81
        self.text_key_references = {}
676 by Martin Pool
- lock branch while checking
82
1449 by Robert Collins
teach check about ghosts
83
    def check(self):
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
84
        self.repository.lock_read()
1594.1.3 by Robert Collins
Fixup pb usage to use nested_progress_bar.
85
        self.progress = bzrlib.ui.ui_factory.nested_progress_bar()
1449 by Robert Collins
teach check about ghosts
86
        try:
2819.2.3 by Andrew Bennetts
Add test that repo.check will report on wrong parents in the revision graph.
87
            self.progress.update('retrieving inventory', 0, 2)
1510 by Robert Collins
Merge from mpool, adjusting check to retain HTTP support.
88
            # do not put in init, as it should be done with progess,
89
            # and inside the lock.
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
90
            self.inventory_weave = self.repository.inventories
2819.2.3 by Andrew Bennetts
Add test that repo.check will report on wrong parents in the revision graph.
91
            self.progress.update('checking revision graph', 1)
92
            self.check_revision_graph()
1510 by Robert Collins
Merge from mpool, adjusting check to retain HTTP support.
93
            self.plan_revisions()
94
            revno = 0
95
            while revno < len(self.planned_revisions):
96
                rev_id = self.planned_revisions[revno]
97
                self.progress.update('checking revision', revno,
1449 by Robert Collins
teach check about ghosts
98
                                     len(self.planned_revisions))
1510 by Robert Collins
Merge from mpool, adjusting check to retain HTTP support.
99
                revno += 1
1449 by Robert Collins
teach check about ghosts
100
                self.check_one_rev(rev_id)
2745.6.16 by Aaron Bentley
Update from review
101
            # check_weaves is done after the revision scan so that
2988.1.8 by Robert Collins
Change check and reconcile to use the new _generate_text_key_index rather
102
            # revision index is known to be valid.
2745.6.3 by Aaron Bentley
Implement versionedfile checking for bzr check
103
            self.check_weaves()
1185.35.34 by Aaron Bentley
Made bzr check for stored revisions missing from ancestry
104
        finally:
1594.1.3 by Robert Collins
Fixup pb usage to use nested_progress_bar.
105
            self.progress.finished()
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
106
            self.repository.unlock()
1449 by Robert Collins
teach check about ghosts
107
2819.2.3 by Andrew Bennetts
Add test that repo.check will report on wrong parents in the revision graph.
108
    def check_revision_graph(self):
2819.2.4 by Andrew Bennetts
Add a 'revision_graph_can_have_wrong_parents' method to repository.
109
        if not self.repository.revision_graph_can_have_wrong_parents():
110
            # This check is not necessary.
2819.2.3 by Andrew Bennetts
Add test that repo.check will report on wrong parents in the revision graph.
111
            self.revs_with_bad_parents_in_index = None
112
            return
113
        bad_revisions = self.repository._find_inconsistent_revision_parents()
114
        self.revs_with_bad_parents_in_index = list(bad_revisions)
115
1510 by Robert Collins
Merge from mpool, adjusting check to retain HTTP support.
116
    def plan_revisions(self):
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
117
        repository = self.repository
3221.17.2 by Ian Clatworthy
back out unnecessary list() around repo.all_revision_ids in check.py
118
        self.planned_revisions = repository.all_revision_ids()
1563.2.22 by Robert Collins
Move responsibility for repository.has_revision into RevisionStore
119
        self.progress.clear()
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
120
        inventoried = set(key[-1] for key in self.inventory_weave.keys())
2745.6.3 by Aaron Bentley
Implement versionedfile checking for bzr check
121
        awol = set(self.planned_revisions) - inventoried
1510 by Robert Collins
Merge from mpool, adjusting check to retain HTTP support.
122
        if len(awol) > 0:
123
            raise BzrCheckError('Stored revisions missing from inventory'
124
                '{%s}' % ','.join([f for f in awol]))
125
1449 by Robert Collins
teach check about ghosts
126
    def report_results(self, verbose):
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
127
        note('checked repository %s format %s',
128
             self.repository.bzrdir.root_transport,
129
             self.repository._format)
1365 by Martin Pool
- try to avoid checking texts repeatedly
130
        note('%6d revisions', self.checked_rev_cnt)
2745.6.47 by Andrew Bennetts
Move check_parents out of VersionedFile.
131
        note('%6d file-ids', len(self.checked_weaves))
1365 by Martin Pool
- try to avoid checking texts repeatedly
132
        note('%6d unique file texts', self.checked_text_cnt)
133
        note('%6d repeated file texts', self.repeated_text_cnt)
2988.1.8 by Robert Collins
Change check and reconcile to use the new _generate_text_key_index rather
134
        note('%6d unreferenced text versions',
135
             len(self.unreferenced_versions))
1348 by Martin Pool
- more refactoring of check code
136
        if self.missing_inventory_sha_cnt:
1449 by Robert Collins
teach check about ghosts
137
            note('%6d revisions are missing inventory_sha1',
1383 by Martin Pool
- untabify only
138
                 self.missing_inventory_sha_cnt)
1348 by Martin Pool
- more refactoring of check code
139
        if self.missing_revision_cnt:
1449 by Robert Collins
teach check about ghosts
140
            note('%6d revisions are mentioned but not present',
1383 by Martin Pool
- untabify only
141
                 self.missing_revision_cnt)
1449 by Robert Collins
teach check about ghosts
142
        if len(self.ghosts):
143
            note('%6d ghost revisions', len(self.ghosts))
144
            if verbose:
145
                for ghost in self.ghosts:
146
                    note('      %s', ghost)
147
        if len(self.missing_parent_links):
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
148
            note('%6d revisions missing parents in ancestry',
1449 by Robert Collins
teach check about ghosts
149
                 len(self.missing_parent_links))
150
            if verbose:
151
                for link, linkers in self.missing_parent_links.items():
152
                    note('      %s should be in the ancestry for:', link)
153
                    for linker in linkers:
154
                        note('       * %s', linker)
2745.6.6 by Aaron Bentley
Add unreferenced ancestors to check output
155
            if verbose:
2988.1.8 by Robert Collins
Change check and reconcile to use the new _generate_text_key_index rather
156
                for file_id, revision_id in self.unreferenced_versions:
157
                    log_error('unreferenced version: {%s} in %s', revision_id,
2745.6.6 by Aaron Bentley
Add unreferenced ancestors to check output
158
                        file_id)
2745.6.39 by Andrew Bennetts
Use scenario in test_check too, and make check actually report inconsistent parents to the end user.
159
        if len(self.inconsistent_parents):
160
            note('%6d inconsistent parents', len(self.inconsistent_parents))
161
            if verbose:
162
                for info in self.inconsistent_parents:
163
                    revision_id, file_id, found_parents, correct_parents = info
164
                    note('      * %s version %s has parents %r '
165
                         'but should have %r'
166
                         % (file_id, revision_id, found_parents,
167
                             correct_parents))
2819.2.3 by Andrew Bennetts
Add test that repo.check will report on wrong parents in the revision graph.
168
        if self.revs_with_bad_parents_in_index:
169
            note('%6d revisions have incorrect parents in the revision index',
170
                 len(self.revs_with_bad_parents_in_index))
171
            if verbose:
172
                for item in self.revs_with_bad_parents_in_index:
173
                    revision_id, index_parents, actual_parents = item
174
                    note(
175
                        '       %s has wrong parents in index: '
176
                        '%r should be %r',
177
                        revision_id, index_parents, actual_parents)
1449 by Robert Collins
teach check about ghosts
178
179
    def check_one_rev(self, rev_id):
1383 by Martin Pool
- untabify only
180
        """Check one revision.
181
182
        rev_id - the one to check
183
        """
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
184
        rev = self.repository.get_revision(rev_id)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
185
1383 by Martin Pool
- untabify only
186
        if rev.revision_id != rev_id:
187
            raise BzrCheckError('wrong internal revision id in revision {%s}'
188
                                % rev_id)
189
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
190
        for parent in rev.parent_ids:
191
            if not parent in self.planned_revisions:
4084.4.1 by Robert Collins
Minor comments clarifying check.py.
192
                # rev has a parent we didn't know about.
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
193
                missing_links = self.missing_parent_links.get(parent, [])
194
                missing_links.append(rev_id)
195
                self.missing_parent_links[parent] = missing_links
196
                # list based so somewhat slow,
197
                # TODO have a planned_revisions list and set.
198
                if self.repository.has_revision(parent):
199
                    missing_ancestry = self.repository.get_ancestry(parent)
200
                    for missing in missing_ancestry:
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
201
                        if (missing is not None
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
202
                            and missing not in self.planned_revisions):
203
                            self.planned_revisions.append(missing)
1449 by Robert Collins
teach check about ghosts
204
                else:
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
205
                    self.ghosts.append(rev_id)
1383 by Martin Pool
- untabify only
206
207
        if rev.inventory_sha1:
4084.4.1 by Robert Collins
Minor comments clarifying check.py.
208
            # Loopback - this is currently circular logic as the
209
            # knit get_inventory_sha1 call returns rev.inventory_sha1.
210
            # Repository.py's get_inventory_sha1 should instead return
211
            # inventories.get_record_stream([(revid,)]).next().sha1 or
212
            # similar.
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
213
            inv_sha1 = self.repository.get_inventory_sha1(rev_id)
1383 by Martin Pool
- untabify only
214
            if inv_sha1 != rev.inventory_sha1:
215
                raise BzrCheckError('Inventory sha1 hash doesn\'t match'
216
                    ' value in revision {%s}' % rev_id)
217
        self._check_revision_tree(rev_id)
1362 by Martin Pool
- keep track of number of checked revisions
218
        self.checked_rev_cnt += 1
1349 by Martin Pool
- more refactoring of check code
219
1185.50.28 by John Arbash Meinel
Lots of updates for 'bzr check'
220
    def check_weaves(self):
221
        """Check all the weaves we can get our hands on.
222
        """
223
        weave_ids = []
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
224
        self.progress.update('checking inventory', 0, 2)
1185.50.28 by John Arbash Meinel
Lots of updates for 'bzr check'
225
        self.inventory_weave.check(progress_bar=self.progress)
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
226
        self.progress.update('checking text storage', 1, 2)
227
        self.repository.texts.check(progress_bar=self.progress)
4145.2.1 by Ian Clatworthy
faster check
228
        weave_checker = self.repository._get_versioned_file_checker(
229
            text_key_references=self.text_key_references)
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
230
        result = weave_checker.check_file_version_parents(
231
            self.repository.texts, progress_bar=self.progress)
232
        self.checked_weaves = weave_checker.file_ids
233
        bad_parents, unused_versions = result
234
        bad_parents = bad_parents.items()
235
        for text_key, (stored_parents, correct_parents) in bad_parents:
236
            # XXX not ready for id join/split operations.
237
            weave_id = text_key[0]
238
            revision_id = text_key[-1]
239
            weave_parents = tuple([parent[-1] for parent in stored_parents])
240
            correct_parents = tuple([parent[-1] for parent in correct_parents])
241
            self.inconsistent_parents.append(
242
                (revision_id, weave_id, weave_parents, correct_parents))
243
        self.unreferenced_versions.update(unused_versions)
1185.50.28 by John Arbash Meinel
Lots of updates for 'bzr check'
244
1349 by Martin Pool
- more refactoring of check code
245
    def _check_revision_tree(self, rev_id):
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
246
        tree = self.repository.revision_tree(rev_id)
1383 by Martin Pool
- untabify only
247
        inv = tree.inventory
4145.2.1 by Ian Clatworthy
faster check
248
        seen_ids = set()
249
        seen_names = set()
250
        for path, ie in inv.iter_entries():
251
            self._add_entry_to_text_key_references(inv, ie)
252
            file_id = ie.file_id
1383 by Martin Pool
- untabify only
253
            if file_id in seen_ids:
254
                raise BzrCheckError('duplicated file_id {%s} '
255
                                    'in inventory for revision {%s}'
256
                                    % (file_id, rev_id))
4145.2.1 by Ian Clatworthy
faster check
257
            seen_ids.add(file_id)
1092.2.20 by Robert Collins
symlink and weaves, whaddya know
258
            ie.check(self, rev_id, inv, tree)
1383 by Martin Pool
- untabify only
259
            if path in seen_names:
260
                raise BzrCheckError('duplicated path %s '
261
                                    'in inventory for revision {%s}'
262
                                    % (path, rev_id))
4145.2.1 by Ian Clatworthy
faster check
263
            seen_names.add(path)
264
265
    def _add_entry_to_text_key_references(self, inv, entry):
266
        if not self.rich_roots and entry == inv.root:
267
            return
268
        key = (entry.file_id, entry.revision)
269
        self.text_key_references.setdefault(key, False)
270
        if entry.revision == inv.revision_id:
271
            self.text_key_references[key] = True
1349 by Martin Pool
- more refactoring of check code
272
1347 by Martin Pool
- refactor check code into method object
273
3015.3.59 by Daniel Watkins
Further tweaks as requested on-list.
274
@deprecated_function(deprecated_in((1,6,0)))
3015.3.35 by Daniel Watkins
Reintroduced bzrlib.check.check() with a deprecation warning.
275
def check(branch, verbose):
276
    """Run consistency checks on a branch.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
277
3015.3.35 by Daniel Watkins
Reintroduced bzrlib.check.check() with a deprecation warning.
278
    Results are reported through logging.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
279
3015.3.58 by Daniel Watkins
Various other cleanup as requested by reviews.
280
    Deprecated in 1.6.  Please use check_branch instead.
3015.3.37 by Daniel Watkins
Added deprecation comment to docstring.
281
3015.3.35 by Daniel Watkins
Reintroduced bzrlib.check.check() with a deprecation warning.
282
    :raise BzrCheckError: if there's a consistency error.
283
    """
284
    check_branch(branch, verbose)
285
286
3015.3.7 by Daniel Watkins
Fixed failing tests.
287
def check_branch(branch, verbose):
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
288
    """Run consistency checks on a branch.
3015.3.35 by Daniel Watkins
Reintroduced bzrlib.check.check() with a deprecation warning.
289
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
290
    Results are reported through logging.
3015.3.35 by Daniel Watkins
Reintroduced bzrlib.check.check() with a deprecation warning.
291
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
292
    :raise BzrCheckError: if there's a consistency error.
293
    """
294
    branch.lock_read()
295
    try:
4332.3.7 by Robert Collins
Convert Branch.check to take a refs dict as well.
296
        needed_refs = branch._get_check_refs()
297
        refs = {}
298
        distances = set()
299
        existences = set()
300
        for ref in needed_refs:
301
            kind, value = ref
302
            if kind == 'lefthand-distance':
303
                distances.add(value)
304
            elif kind == 'revision-existence':
305
                existences.add(value)
306
            else:
307
                raise AssertionError(
308
                    'unknown ref kind for ref %s' % ref)
309
        node_distances = branch.repository.get_graph().find_lefthand_distances(
310
            distances)
311
        for key, distance in node_distances.iteritems():
312
            refs[('lefthand-distance', key)] = distance
313
            if key in existences and distance > 0:
314
                refs[('revision-existence', key)] = True
315
                existences.remove(key)
316
        parent_map = branch.repository.get_graph().get_parent_map(existences)
317
        for key in parent_map:
318
            refs[('revision-existence', key)] = True
319
            existences.remove(key)
320
        for key in existences:
321
            refs[('revision-existence', key)] = False
322
        branch_result = branch.check(refs)
1732.2.4 by Martin Pool
Split check into Branch.check and Repository.check
323
    finally:
324
        branch.unlock()
325
    branch_result.report_results(verbose)
2745.6.47 by Andrew Bennetts
Move check_parents out of VersionedFile.
326
327
3015.4.5 by Daniel Watkins
Each option selects only the specific thing to be checked.
328
def check_dwim(path, verbose, do_branch=False, do_repo=False, do_tree=False):
3015.4.16 by Daniel Watkins
Added implementation of error reporting when objects are missing.
329
    try:
330
        tree, branch, repo, relpath = \
3015.4.11 by Daniel Watkins
Fixed long line.
331
                        BzrDir.open_containing_tree_branch_or_repository(path)
3015.4.16 by Daniel Watkins
Added implementation of error reporting when objects are missing.
332
    except errors.NotBranchError:
333
        tree = branch = repo = None
3015.3.23 by Daniel Watkins
Abstracted discovery of elements away.
334
3015.4.5 by Daniel Watkins
Each option selects only the specific thing to be checked.
335
    if do_tree:
336
        if tree is not None:
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
337
            note("Checking working tree at '%s'."
3015.4.5 by Daniel Watkins
Each option selects only the specific thing to be checked.
338
                 % (tree.bzrdir.root_transport.base,))
4332.3.2 by Robert Collins
Extract repository access in WorkingTree._check to be data driven, adding a new _get_check_refs method to support this.
339
            tree.lock_read()
340
            try:
341
                needed_refs = tree._get_check_refs()
342
                refs = {}
343
                for ref in needed_refs:
344
                    kind, value = ref
345
                    if kind == 'trees':
346
                        refs[ref] = tree.branch.repository.revision_tree(value)
347
                    else:
348
                        raise AssertionError(
349
                            'unknown ref kind for ref %s' % ref)
350
                tree._check(refs)
351
            finally:
352
                tree.unlock()
3015.4.16 by Daniel Watkins
Added implementation of error reporting when objects are missing.
353
        else:
354
            log_error("No working tree found at specified location.")
3015.3.23 by Daniel Watkins
Abstracted discovery of elements away.
355
3015.4.5 by Daniel Watkins
Each option selects only the specific thing to be checked.
356
    if branch is not None:
3015.3.20 by Daniel Watkins
Made code path a little clearer.
357
        # We have a branch
3015.3.5 by Daniel Watkins
Removed needless duplication of repository checks.
358
        if repo is None:
3015.3.10 by Daniel Watkins
Reorganised comments.
359
            # The branch is in a shared repository
3015.3.5 by Daniel Watkins
Removed needless duplication of repository checks.
360
            repo = branch.repository
3015.3.18 by Daniel Watkins
Improved errors.
361
        branches = [branch]
3015.3.59 by Daniel Watkins
Further tweaks as requested on-list.
362
    elif repo is not None:
363
        branches = repo.find_branches(using=True)
3015.3.9 by Daniel Watkins
Scan for branches and check them.
364
3015.3.4 by Daniel Watkins
If not in a branch or a repo, that check is simply skipped.
365
    if repo is not None:
3015.3.21 by Daniel Watkins
Fixed misused 'repository'.
366
        repo.lock_read()
3015.3.19 by Daniel Watkins
Repositories are now held read-locked for as long as possible.
367
        try:
3015.4.3 by Daniel Watkins
Implemented CLI options.
368
            if do_repo:
369
                note("Checking repository at '%s'."
370
                     % (repo.bzrdir.root_transport.base,))
371
                result = repo.check()
372
                result.report_results(verbose)
373
            if do_branch:
3015.4.16 by Daniel Watkins
Added implementation of error reporting when objects are missing.
374
                if branches == []:
375
                    log_error("No branch found at specified location.")
376
                else:
377
                    for branch in branches:
378
                        note("Checking branch at '%s'."
379
                             % (branch.bzrdir.root_transport.base,))
380
                        check_branch(branch, verbose)
3015.3.19 by Daniel Watkins
Repositories are now held read-locked for as long as possible.
381
        finally:
3015.3.21 by Daniel Watkins
Fixed misused 'repository'.
382
            repo.unlock()
3015.4.16 by Daniel Watkins
Added implementation of error reporting when objects are missing.
383
    else:
384
        if do_branch:
385
            log_error("No branch found at specified location.")
386
        if do_repo:
387
            log_error("No repository found at specified location.")