1
# Copyright (C) 2004, 2005 by Martin Pool
2
# Copyright (C) 2005 by Canonical Ltd
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
# GNU General Public License for more details.
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
"""Run consistency checks on a branch.
26
from bzrlib.trace import mutter
27
from bzrlib.errors import BzrCheckError
28
from bzrlib.osutils import fingerprint_file
29
from bzrlib.progress import ProgressBar
33
pb = ProgressBar(show_spinner=True)
37
history = branch.revision_history()
39
revcount = len(history)
45
pb.update('checking revision', revno, revcount)
46
mutter(' revision {%s}' % rid)
47
rev = branch.get_revision(rid)
48
if rev.revision_id != rid:
49
raise BzrCheckError('wrong internal revision id in revision {%s}' % rid)
50
if rev.precursor != last_ptr:
51
raise BzrCheckError('mismatched precursor in revision {%s}' % rid)
53
if rid in checked_revs:
54
raise BzrCheckError('repeated revision {%s}' % rid)
55
checked_revs[rid] = True
57
## TODO: Check all the required fields are present on the revision.
59
inv = branch.get_inventory(rev.inventory_id)
63
## p('revision %d/%d file ids' % (revno, revcount))
65
if file_id in seen_ids:
66
raise BzrCheckError('duplicated file_id {%s} '
67
'in inventory for revision {%s}'
69
seen_ids[file_id] = True
80
if ie.parent_id != None:
81
if ie.parent_id not in seen_ids:
82
raise BzrCheckError('missing parent {%s} in inventory for revision {%s}'
83
% (ie.parent_id, rid))
86
if ie.text_id in checked_texts:
87
fp = checked_texts[ie.text_id]
89
if not ie.text_id in branch.text_store:
90
raise BzrCheckError('text {%s} not in text_store' % ie.text_id)
92
tf = branch.text_store[ie.text_id]
93
fp = fingerprint_file(tf)
94
checked_texts[ie.text_id] = fp
96
if ie.text_size != fp['size']:
97
raise BzrCheckError('text {%s} wrong size' % ie.text_id)
98
if ie.text_sha1 != fp['sha1']:
99
raise BzrCheckError('text {%s} wrong sha1' % ie.text_id)
100
elif ie.kind == 'directory':
101
if ie.text_sha1 != None or ie.text_size != None or ie.text_id != None:
102
raise BzrCheckError('directory {%s} has text in revision {%s}'
106
for path, ie in inv.iter_entries():
107
if path in seen_names:
108
raise BzrCheckError('duplicated path %r '
109
'in inventory for revision {%s}'
111
seen_names[path] = True
115
print 'checked %d revisions, %d file texts' % (revcount, len(checked_texts))