533
532
return find_ids_across_trees(paths, [self] + list(trees), require_versioned)
535
534
def iter_children(self, file_id):
536
entry = self.iter_entries_by_dir([file_id]).next()[1]
537
for child in getattr(entry, 'children', {}).itervalues():
535
"""Iterate over the file ids of the children of an entry.
537
:param file_id: File id of the entry
538
:return: Iterator over child file ids.
540
raise NotImplementedError(self.iter_children)
540
542
def lock_read(self):
541
543
"""Lock this tree for multiple read only operations.
543
545
:return: A bzrlib.lock.LogicalLockResult.
774
@deprecated_method(deprecated_in((2, 5, 0)))
772
775
def _get_inventory(self):
773
776
return self._inventory
775
778
inventory = property(_get_inventory,
776
779
doc="Inventory of this Tree")
781
def _get_root_inventory(self):
782
return self._inventory
784
root_inventory = property(_get_root_inventory,
785
doc="Root inventory of this tree")
787
def _unpack_file_id(self, file_id):
788
"""Find the inventory and inventory file id for a tree file id.
790
:param file_id: The tree file id, as bytestring or tuple
791
:return: Inventory and inventory file id
793
if isinstance(file_id, tuple):
794
if len(file_id) != 1:
795
raise ValueError("nested trees not yet supported: %r" % file_id)
797
return self.root_inventory, file_id
779
800
def path2id(self, path):
780
801
"""Return the id for path in this tree."""
781
return self._inventory.path2id(path)
802
return self._path2inv_file_id(path)[1]
804
def _path2inv_file_id(self, path):
805
"""Lookup a inventory and inventory file id by path.
807
:param path: Path to look up
808
:return: tuple with inventory and inventory file id
810
# FIXME: Support nested trees
811
return self.root_inventory, self.root_inventory.path2id(path)
783
813
def id2path(self, file_id):
784
814
"""Return the path for a file id.
786
816
:raises NoSuchId:
788
return self.inventory.id2path(file_id)
818
inventory, file_id = self._unpack_file_id(file_id)
819
return inventory.id2path(file_id)
790
821
def has_id(self, file_id):
791
return self.inventory.has_id(file_id)
822
inventory, file_id = self._unpack_file_id(file_id)
823
return inventory.has_id(file_id)
793
825
def has_or_had_id(self, file_id):
794
return self.inventory.has_id(file_id)
826
inventory, file_id = self._unpack_file_id(file_id)
827
return inventory.has_id(file_id)
796
829
def all_file_ids(self):
797
return set(self.inventory)
831
[entry.file_id for path, entry in self.iter_entries_by_dir()])
799
833
@deprecated_method(deprecated_in((2, 4, 0)))
800
834
def __iter__(self):
801
return iter(self.inventory)
835
return iter(self.all_file_ids())
803
837
def filter_unversioned_files(self, paths):
804
838
"""Filter out paths that are versioned.
808
842
# NB: we specifically *don't* call self.has_filename, because for
809
843
# WorkingTrees that can indicate files that exist on disk but that
810
844
# are not versioned.
811
pred = self.inventory.has_filename
812
return set((p for p in paths if not pred(p)))
845
return set((p for p in paths if self.path2id(p) is None))
815
848
def iter_entries_by_dir(self, specific_file_ids=None, yield_parents=False):
824
857
down to specific_file_ids that have been requested. This has no
825
858
impact if specific_file_ids is None.
827
return self.inventory.iter_entries_by_dir(
828
specific_file_ids=specific_file_ids, yield_parents=yield_parents)
860
if specific_file_ids is None:
861
inventory_file_ids = None
863
inventory_file_ids = []
864
for tree_file_id in specific_file_ids:
865
inventory, inv_file_id = self._unpack_file_id(tree_file_id)
866
if not inventory is self.root_inventory: # for now
867
raise AssertionError("%r != %r" % (
868
inventory, self.root_inventory))
869
inventory_file_ids.append(inv_file_id)
870
# FIXME: Handle nested trees
871
return self.root_inventory.iter_entries_by_dir(
872
specific_file_ids=inventory_file_ids, yield_parents=yield_parents)
874
@deprecated_method(deprecated_in((2, 5, 0)))
830
875
def get_file_by_path(self, path):
831
return self.get_file(self._inventory.path2id(path), path)
876
return self.get_file(self.path2id(path), path)
878
def iter_children(self, file_id, path=None):
879
"""See Tree.iter_children."""
880
entry = self.iter_entries_by_dir([file_id]).next()[1]
881
for child in getattr(entry, 'children', {}).itervalues():
834
885
def find_ids_across_trees(filenames, trees, require_versioned=True):
989
1040
if (self.source.get_symlink_target(file_id) !=
990
1041
self.target.get_symlink_target(file_id)):
991
1042
changed_content = True
992
# XXX: Yes, the indentation below is wrong. But fixing it broke
993
# test_merge.TestMergerEntriesLCAOnDisk.
994
# test_nested_tree_subtree_renamed_and_modified. We'll wait for
995
# the fix from bzr.dev -- vila 2009026
996
elif source_kind == 'tree-reference':
997
if (self.source.get_reference_revision(file_id, source_path)
998
!= self.target.get_reference_revision(file_id, target_path)):
1043
elif source_kind == 'tree-reference':
1044
if (self.source.get_reference_revision(file_id, source_path)
1045
!= self.target.get_reference_revision(file_id, target_path)):
999
1046
changed_content = True
1000
1047
parent = (source_parent, target_parent)
1001
1048
name = (source_name, target_name)
1297
1344
if old_entry is None:
1298
1345
# Reusing a discarded change.
1299
1346
old_entry = self._get_entry(self.source, file_id)
1300
for child in old_entry.children.values():
1301
precise_file_ids.add(child.file_id)
1347
for child in self.source.iter_children(file_id):
1348
precise_file_ids.add(child)
1302
1349
changed_file_ids.add(result[0])