227
def add_sha(rev_id, sha1):
226
def add_sha(d, rev_id, sha1):
228
227
if rev_id is None:
229
228
if sha1 is not None:
230
229
raise BzrError('A Null revision should always'
231
230
'have a null sha1 hash')
233
if rev_id in rev_to_sha:
234
233
# This really should have been validated as part
235
234
# of _validate_revisions but lets do it again
236
if sha1 != rev_to_sha[rev_id]:
235
if sha1 != d[rev_id]:
237
236
raise BzrError('** Revision %r referenced with 2 different'
238
237
' sha hashes %s != %s' % (rev_id,
239
sha1, rev_to_sha[rev_id]))
241
rev_to_sha[rev_id] = sha1
243
add_sha(self.info.base, self.info.base_sha1)
242
add_sha(rev_to_sha, self.info.base, self.info.base_sha1)
244
243
# All of the contained revisions were checked
245
244
# in _validate_revisions
247
246
for rev_info in self.info.revisions:
248
247
checked[rev_info.rev_id] = True
249
add_sha(rev_info.rev_id, rev_info.sha1)
248
add_sha(rev_to_sha, rev_info.rev_id, rev_info.sha1)
251
250
for rev in self.info.real_revisions:
251
add_sha(inv_to_sha, rev_info.inventory_id, rev_info.inventory_sha1)
252
252
for parent in rev.parents:
253
add_sha(parent.revision_id, parent.revision_sha1)
253
add_sha(rev_to_sha, parent.revision_id, parent.revision_sha1)
256
257
for rev_id, sha1 in rev_to_sha.iteritems():
257
258
if rev_id in branch.revision_store:
258
259
local_sha1 = branch.get_revision_sha1(rev_id)
259
260
if sha1 != local_sha1:
260
raise BzrError('sha1 mismatch. For revision_id {%s}'
261
raise BzrError('sha1 mismatch. For revision id {%s}'
261
262
'local: %s, cset: %s' % (rev_id, local_sha1, sha1))
262
265
elif rev_id not in checked:
263
266
missing[rev_id] = sha1
268
for inv_id, sha1 in inv_to_sha.iteritems():
269
if inv_id in branch.inventory_store:
270
local_sha1 = branch.get_inventory_sha1(inv_id)
271
if sha1 != local_sha1:
272
raise BzrError('sha1 mismatch. For inventory id {%s}'
273
'local: %s, cset: %s' % (inv_id, local_sha1, sha1))
265
277
if len(missing) > 0:
266
278
# I don't know if this is an error yet
267
279
from bzrlib.trace import warning
268
280
warning('Not all revision hashes could be validated.'
269
281
' Unable validate %d hashes' % len(missing))
271
def _validate_inventory(self, branch, tree):
282
mutter('Verified %d sha hashes for the changeset.' % count)
284
def _create_inventory(self, tree):
285
"""Build up the inventory entry for the ChangesetTree.
287
TODO: This sort of thing should probably end up part of
288
ChangesetTree, but since it doesn't handle meta-information
289
yet, we need to do it here. (We need the ChangesetInfo,
290
specifically the text_ids)
292
from os.path import dirname, basename
293
from bzrlib.inventory import Inventory, InventoryEntry, ROOT_ID
295
# TODO: deal with trees having a unique ROOT_ID
299
if file_id == root_id:
301
path = tree.id2path(file_id)
302
parent_path = dirname(path)
306
parent_id = tree.path2id(parent_path)
308
if self.info.text_ids.has_key(file_id):
309
text_id = self.info.text_ids[file_id]
311
# If we don't have the text_id in the local map
312
# that means the file didn't exist in the changeset
313
# so we just use the old text_id.
314
text_id = tree.base_tree.inventory[file_id].text_id
315
name = basename(path)
316
kind = tree.get_kind(file_id)
317
ie = InventoryEntry(file_id, name, kind, parent_id, text_id=text_id)
318
ie.text_size, ie.text_sha1 = tree.get_size_and_sha1(file_id)
319
if ie.text_size is None:
320
raise BzrError('Got a text_size of None for file_id %r' % file_id)
324
def _validate_inventory(self, inv):
272
325
"""At this point we should have generated the ChangesetTree,
273
326
so build up an inventory, and make sure the hashes match.
328
from bzrlib.xml import pack_xml
329
from cStringIO import StringIO
330
from bzrlib.osutils import sha_file, pumpfile
332
# Now we should have a complete inventory entry.
337
# Target revision is the last entry in the real_revisions list
338
rev = self.info.real_revisions[-1]
339
if sha1 != rev.inventory_sha1:
340
raise BzrError('Inventory sha hash mismatch.')
276
def get_info_and_tree(self, branch):
343
def get_info_tree_inv(self, branch):
277
344
"""Return the meta information, and a Changeset tree which can
278
345
be used to populate the local stores and working tree, respectively.
752
821
return patch_original
753
822
return patched_file(file_patch, patch_original)
824
def get_kind(self, file_id):
825
if file_id in self._kinds:
826
return self._kinds[file_id]
827
return self.base_tree.inventory[file_id].kind
829
def get_size_and_sha1(self, file_id):
830
"""Return the size and sha1 hash of the given file id.
831
If the file was not locally modified, this is extracted
832
from the base_tree. Rather than re-reading the file.
834
from bzrlib.osutils import sha_string
836
new_path = self.id2path(file_id)
839
if new_path not in self.patches:
840
# If the entry does not have a patch, then the
841
# contents must be the same as in the base_tree
842
ie = self.base_tree.inventory[file_id]
843
return int(ie.text_size), ie.text_sha1
844
content = self.get_file(file_id).read()
845
return len(content), sha_string(content)
755
849
def __iter__(self):
756
850
for file_id in self._new_id_r.iterkeys():