251
250
if self.parent_id is not None:
252
251
if not inv.has_id(self.parent_id):
253
raise BzrCheckError('missing parent {%s} in inventory for revision {%s}'
254
% (self.parent_id, rev_id))
252
raise errors.BzrCheckError(
253
'missing parent {%s} in inventory for revision {%s}' % (
254
self.parent_id, rev_id))
255
255
checker._add_entry_to_text_key_references(inv, self)
256
256
self._check(checker, rev_id)
718
718
# if we finished all children, pop it off the stack
721
def _preload_cache(self):
722
"""Populate any caches, we are about to access all items.
724
The default implementation does nothing, because CommonInventory doesn't
721
729
def iter_entries_by_dir(self, from_dir=None, specific_file_ids=None,
722
730
yield_parents=False):
723
731
"""Iterate over the entries in a directory first order.
736
744
specific_file_ids = set(specific_file_ids)
737
745
# TODO? Perhaps this should return the from_dir so that the root is
738
746
# yielded? or maybe an option?
747
if from_dir is None and specific_file_ids is None:
748
# They are iterating from the root, and have not specified any
749
# specific entries to look at. All current callers fully consume the
750
# iterator, so we can safely assume we are accessing all entries
751
self._preload_cache()
739
752
if from_dir is None:
740
753
if self.root is None:
1169
1182
def _add_child(self, entry):
1170
1183
"""Add an entry to the inventory, without adding it to its parent"""
1171
1184
if entry.file_id in self._byid:
1172
raise BzrError("inventory already contains entry with id {%s}" %
1185
raise errors.BzrError(
1186
"inventory already contains entry with id {%s}" %
1174
1188
self._byid[entry.file_id] = entry
1175
1189
for child in getattr(entry, 'children', {}).itervalues():
1176
1190
self._add_child(child)
1341
1355
new_name = ensure_normalized_name(new_name)
1342
1356
if not is_valid_name(new_name):
1343
raise BzrError("not an acceptable filename: %r" % new_name)
1357
raise errors.BzrError("not an acceptable filename: %r" % new_name)
1345
1359
new_parent = self._byid[new_parent_id]
1346
1360
if new_name in new_parent.children:
1347
raise BzrError("%r already exists in %r" % (new_name, self.id2path(new_parent_id)))
1361
raise errors.BzrError("%r already exists in %r" %
1362
(new_name, self.id2path(new_parent_id)))
1349
1364
new_parent_idpath = self.get_idpath(new_parent_id)
1350
1365
if file_id in new_parent_idpath:
1351
raise BzrError("cannot move directory %r into a subdirectory of itself, %r"
1366
raise errors.BzrError(
1367
"cannot move directory %r into a subdirectory of itself, %r"
1352
1368
% (self.id2path(file_id), self.id2path(new_parent_id)))
1354
1370
file_ie = self._byid[file_id]
1970
1987
self._fileid_to_entry_cache[file_id] = ie
1990
def _preload_cache(self):
1991
"""Make sure all file-ids are in _fileid_to_entry_cache"""
1992
if self._fully_cached:
1993
return # No need to do it again
1994
# The optimal sort order is to use iteritems() directly
1995
cache = self._fileid_to_entry_cache
1996
for key, entry in self.id_to_entry.iteritems():
1998
if file_id not in cache:
1999
ie = self._bytes_to_entry(entry)
2003
last_parent_id = last_parent_ie = None
2004
pid_items = self.parent_id_basename_to_file_id.iteritems()
2005
for key, child_file_id in pid_items:
2006
if key == ('', ''): # This is the root
2007
if child_file_id != self.root_id:
2008
raise ValueError('Data inconsistency detected.'
2009
' We expected data with key ("","") to match'
2010
' the root id, but %s != %s'
2011
% (child_file_id, self.root_id))
2013
parent_id, basename = key
2014
ie = cache[child_file_id]
2015
if parent_id == last_parent_id:
2016
parent_ie = last_parent_ie
2018
parent_ie = cache[parent_id]
2019
if parent_ie.kind != 'directory':
2020
raise ValueError('Data inconsistency detected.'
2021
' An entry in the parent_id_basename_to_file_id map'
2022
' has parent_id {%s} but the kind of that object'
2023
' is %r not "directory"' % (parent_id, parent_ie.kind))
2024
if parent_ie._children is None:
2025
parent_ie._children = {}
2026
basename = basename.decode('utf-8')
2027
if basename in parent_ie._children:
2028
existing_ie = parent_ie._children[basename]
2029
if existing_ie != ie:
2030
raise ValueError('Data inconsistency detected.'
2031
' Two entries with basename %r were found'
2032
' in the parent entry {%s}'
2033
% (basename, parent_id))
2034
if basename != ie.name:
2035
raise ValueError('Data inconsistency detected.'
2036
' In the parent_id_basename_to_file_id map, file_id'
2037
' {%s} is listed as having basename %r, but in the'
2038
' id_to_entry map it is %r'
2039
% (child_file_id, basename, ie.name))
2040
parent_ie._children[basename] = ie
2041
self._fully_cached = True
1973
2043
def iter_changes(self, basis):
1974
2044
"""Generate a Tree.iter_changes change list between this and basis.