15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
from bzrlib.trace import note, warning
20
from bzrlib.osutils import rename, sha_string
19
22
def _update_store_entry(obj, obj_id, branch, store_name, store):
20
23
"""This is just a meta-function, which handles both revision entries
70
72
:param inv_id: The inventory id for this inventory
71
73
:param branch: The Branch where this entry will be stored.
73
_update_store_entry(inv, inv_id, branch,
74
'inventory-store', branch.inventory_store)
75
raise NotImplementedError("can't update existing inventory entry")
77
79
"""Run consistency checks on a branch.
81
83
TODO: Check for extra files in the control directory.
83
85
from bzrlib.trace import mutter
84
from bzrlib.errors import BzrCheckError
86
from bzrlib.errors import BzrCheckError, NoSuchRevision
85
87
from bzrlib.osutils import fingerprint_file
86
from bzrlib.progress import ProgressBar
87
88
from bzrlib.inventory import ROOT_ID
88
89
from bzrlib.branch import gen_root_id
93
pb = ProgressBar(show_spinner=True)
96
96
missing_inventory_sha_cnt = 0
97
97
missing_revision_sha_cnt = 0
98
missing_revision_cnt = 0
99
100
history = branch.revision_history()
101
102
revcount = len(history)
104
# for all texts checked, text_id -> sha1
104
checked_text_count = 0
106
progress = bzrlib.ui.ui_factory.progress_bar()
107
108
for rev_id in history:
109
pb.update('checking revision', revno, revcount)
110
mutter(' revision {%s}' % rev_id)
110
progress.update('checking revision', revno, revcount)
111
# mutter(' revision {%s}' % rev_id)
111
112
rev = branch.get_revision(rev_id)
112
113
if rev.revision_id != rev_id:
113
114
raise BzrCheckError('wrong internal revision id in revision {%s}'
119
120
raise BzrCheckError("revision {%s} has %d parents, but is the "
120
121
"start of the branch"
121
122
% (rev_id, len(rev.parents)))
122
for prr in rev.parents:
123
if prr.revision_id == last_rev_id:
123
for parent_id in rev.parents:
124
if parent_id == last_rev_id:
126
127
raise BzrCheckError("previous revision {%s} not listed among "
127
128
"parents of {%s}"
128
129
% (last_rev_id, rev_id))
130
for prr in rev.parents:
131
if prr.revision_sha1 is None:
132
missing_revision_sha_cnt += 1
134
prid = prr.revision_id
135
actual_sha = branch.get_revision_sha1(prid)
136
if prr.revision_sha1 != actual_sha:
137
raise BzrCheckError("mismatched revision sha1 for "
138
"parent {%s} of {%s}: %s vs %s"
140
prr.revision_sha1, actual_sha))
141
130
elif last_rev_id:
142
raise BzrCheckError("revision {%s} has no parents listed but preceded "
131
raise BzrCheckError("revision {%s} has no parents listed "
132
"but preceded by {%s}"
144
133
% (rev_id, last_rev_id))
146
if rev.inventory_id != rev_id:
147
mismatch_inv_id.append(rev_id)
149
135
## TODO: Check all the required fields are present on the revision.
151
137
if rev.inventory_sha1:
152
inv_sha1 = branch.get_inventory_sha1(rev.inventory_id)
138
inv_sha1 = branch.get_inventory_sha1(rev_id)
153
139
if inv_sha1 != rev.inventory_sha1:
154
140
raise BzrCheckError('Inventory sha1 hash doesn\'t match'
155
141
' value in revision {%s}' % rev_id)
183
170
% (ie.parent_id, rev_id))
185
172
if ie.kind == 'file':
186
if ie.text_id in checked_texts:
187
fp = checked_texts[ie.text_id]
189
if not ie.text_id in branch.text_store:
190
raise BzrCheckError('text {%s} not in text_store' % ie.text_id)
192
tf = branch.text_store[ie.text_id]
193
fp = fingerprint_file(tf)
194
checked_texts[ie.text_id] = fp
196
if ie.text_size != fp['size']:
173
text = tree.get_file_text(file_id)
174
checked_text_count += 1
175
if ie.text_size != len(text):
197
176
raise BzrCheckError('text {%s} wrong size' % ie.text_id)
198
if ie.text_sha1 != fp['sha1']:
177
if ie.text_sha1 != sha_string(text):
199
178
raise BzrCheckError('text {%s} wrong sha1' % ie.text_id)
200
179
elif ie.kind == 'directory':
201
180
if ie.text_sha1 != None or ie.text_size != None or ie.text_id != None:
202
181
raise BzrCheckError('directory {%s} has text in revision {%s}'
203
182
% (file_id, rev_id))
206
185
for path, ie in inv.iter_entries():
207
186
if path in seen_names:
208
187
raise BzrCheckError('duplicated path %s '
209
188
'in inventory for revision {%s}'
210
189
% (path, rev_id))
211
seen_names[path] = True
190
seen_names[path] = True
212
191
last_rev_id = rev_id
219
print 'checked %d revisions, %d file texts' % (revcount, len(checked_texts))
198
note('checked %d revisions, %d file texts' % (revcount, checked_text_count))
221
200
if missing_inventory_sha_cnt:
222
print '%d revisions are missing inventory_sha1' % missing_inventory_sha_cnt
224
if missing_revision_sha_cnt:
225
print '%d parent links are missing revision_sha1' % missing_revision_sha_cnt
227
if (missing_inventory_sha_cnt
228
or missing_revision_sha_cnt):
229
print ' (use "bzr upgrade" to fix them)'
232
print '%d revisions have mismatched inventory ids:' % len(mismatch_inv_id)
233
for rev_id in mismatch_inv_id:
201
note('%d revisions are missing inventory_sha1' % missing_inventory_sha_cnt)
203
##if missing_revision_sha_cnt:
204
## note('%d parent links are missing revision_sha1' % missing_revision_sha_cnt)
206
if missing_revision_cnt:
207
note('%d revisions are mentioned but not present' % missing_revision_cnt)
209
if missing_revision_cnt:
210
print '%d revisions are mentioned but not present' % missing_revision_cnt
212
# stub this out for now because the main bzr branch has references
213
# to revisions that aren't present in the store -- mbp 20050804
214
# if (missing_inventory_sha_cnt
215
# or missing_revision_sha_cnt):
216
# print ' (use "bzr upgrade" to fix them)'