~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tree.py

  • Committer: Jelmer Vernooij
  • Date: 2011-09-21 00:30:34 UTC
  • mto: This revision was merged to the branch mainline in revision 6154.
  • Revision ID: jelmer@samba.org-20110921003034-gmyos0opg0orl4bw
Fix typo.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
"""Tree classes, representing directory at point in time.
18
18
"""
19
19
 
20
 
from __future__ import absolute_import
21
 
 
22
20
import os
23
21
 
24
22
from bzrlib.lazy_import import lazy_import
195
193
        """
196
194
        raise NotImplementedError(self.iter_entries_by_dir)
197
195
 
198
 
    def iter_child_entries(self, file_id, path=None):
199
 
        """Iterate over the children of a directory or tree reference.
200
 
 
201
 
        :param file_id: File id of the directory/tree-reference
202
 
        :param path: Optional path of the directory
203
 
        :raise NoSuchId: When the file_id does not exist
204
 
        :return: Iterator over entries in the directory
205
 
        """
206
 
        raise NotImplementedError(self.iter_child_entries)
207
 
 
208
196
    def list_files(self, include_root=False, from_dir=None, recursive=True):
209
197
        """List all files in this tree.
210
198
 
367
355
        """
368
356
        raise NotImplementedError(self.get_file_size)
369
357
 
 
358
    def get_file_by_path(self, path):
 
359
        raise NotImplementedError(self.get_file_by_path)
 
360
 
370
361
    def is_executable(self, file_id, path=None):
371
362
        """Check if a file is executable.
372
363
 
542
533
        return find_ids_across_trees(paths, [self] + list(trees), require_versioned)
543
534
 
544
535
    def iter_children(self, file_id):
545
 
        """Iterate over the file ids of the children of an entry.
546
 
 
547
 
        :param file_id: File id of the entry
548
 
        :return: Iterator over child file ids.
549
 
        """
550
 
        raise NotImplementedError(self.iter_children)
 
536
        entry = self.iter_entries_by_dir([file_id]).next()[1]
 
537
        for child in getattr(entry, 'children', {}).itervalues():
 
538
            yield child.file_id
551
539
 
552
540
    def lock_read(self):
553
541
        """Lock this tree for multiple read only operations.
554
 
 
 
542
        
555
543
        :return: A bzrlib.lock.LogicalLockResult.
556
544
        """
557
545
        pass
781
769
            yield cur_path
782
770
        # all done.
783
771
 
784
 
    @deprecated_method(deprecated_in((2, 5, 0)))
785
772
    def _get_inventory(self):
786
773
        return self._inventory
787
774
 
788
775
    inventory = property(_get_inventory,
789
776
                         doc="Inventory of this Tree")
790
777
 
791
 
    def _get_root_inventory(self):
792
 
        return self._inventory
793
 
 
794
 
    root_inventory = property(_get_root_inventory,
795
 
        doc="Root inventory of this tree")
796
 
 
797
 
    def _unpack_file_id(self, file_id):
798
 
        """Find the inventory and inventory file id for a tree file id.
799
 
 
800
 
        :param file_id: The tree file id, as bytestring or tuple
801
 
        :return: Inventory and inventory file id
802
 
        """
803
 
        if isinstance(file_id, tuple):
804
 
            if len(file_id) != 1:
805
 
                raise ValueError("nested trees not yet supported: %r" % file_id)
806
 
            file_id = file_id[0]
807
 
        return self.root_inventory, file_id
808
 
 
809
778
    @needs_read_lock
810
779
    def path2id(self, path):
811
780
        """Return the id for path in this tree."""
812
 
        return self._path2inv_file_id(path)[1]
813
 
 
814
 
    def _path2inv_file_id(self, path):
815
 
        """Lookup a inventory and inventory file id by path.
816
 
 
817
 
        :param path: Path to look up
818
 
        :return: tuple with inventory and inventory file id
819
 
        """
820
 
        # FIXME: Support nested trees
821
 
        return self.root_inventory, self.root_inventory.path2id(path)
 
781
        return self._inventory.path2id(path)
822
782
 
823
783
    def id2path(self, file_id):
824
784
        """Return the path for a file id.
825
785
 
826
786
        :raises NoSuchId:
827
787
        """
828
 
        inventory, file_id = self._unpack_file_id(file_id)
829
 
        return inventory.id2path(file_id)
 
788
        return self.inventory.id2path(file_id)
830
789
 
831
790
    def has_id(self, file_id):
832
 
        inventory, file_id = self._unpack_file_id(file_id)
833
 
        return inventory.has_id(file_id)
 
791
        return self.inventory.has_id(file_id)
834
792
 
835
793
    def has_or_had_id(self, file_id):
836
 
        inventory, file_id = self._unpack_file_id(file_id)
837
 
        return inventory.has_id(file_id)
 
794
        return self.inventory.has_id(file_id)
838
795
 
839
796
    def all_file_ids(self):
840
 
        return set(
841
 
            [entry.file_id for path, entry in self.iter_entries_by_dir()])
 
797
        return set(self.inventory)
842
798
 
843
799
    @deprecated_method(deprecated_in((2, 4, 0)))
844
800
    def __iter__(self):
845
 
        return iter(self.all_file_ids())
 
801
        return iter(self.inventory)
846
802
 
847
803
    def filter_unversioned_files(self, paths):
848
804
        """Filter out paths that are versioned.
852
808
        # NB: we specifically *don't* call self.has_filename, because for
853
809
        # WorkingTrees that can indicate files that exist on disk but that
854
810
        # are not versioned.
855
 
        return set((p for p in paths if self.path2id(p) is None))
 
811
        pred = self.inventory.has_filename
 
812
        return set((p for p in paths if not pred(p)))
856
813
 
857
814
    @needs_read_lock
858
815
    def iter_entries_by_dir(self, specific_file_ids=None, yield_parents=False):
867
824
            down to specific_file_ids that have been requested. This has no
868
825
            impact if specific_file_ids is None.
869
826
        """
870
 
        if specific_file_ids is None:
871
 
            inventory_file_ids = None
872
 
        else:
873
 
            inventory_file_ids = []
874
 
            for tree_file_id in specific_file_ids:
875
 
                inventory, inv_file_id = self._unpack_file_id(tree_file_id)
876
 
                if not inventory is self.root_inventory: # for now
877
 
                    raise AssertionError("%r != %r" % (
878
 
                        inventory, self.root_inventory))
879
 
                inventory_file_ids.append(inv_file_id)
880
 
        # FIXME: Handle nested trees
881
 
        return self.root_inventory.iter_entries_by_dir(
882
 
            specific_file_ids=inventory_file_ids, yield_parents=yield_parents)
883
 
 
884
 
    @needs_read_lock
885
 
    def iter_child_entries(self, file_id, path=None):
886
 
        inv, inv_file_id = self._unpack_file_id(file_id)
887
 
        return inv[inv_file_id].children.itervalues()
888
 
 
889
 
    @deprecated_method(deprecated_in((2, 5, 0)))
 
827
        return self.inventory.iter_entries_by_dir(
 
828
            specific_file_ids=specific_file_ids, yield_parents=yield_parents)
 
829
 
890
830
    def get_file_by_path(self, path):
891
 
        return self.get_file(self.path2id(path), path)
892
 
 
893
 
    def iter_children(self, file_id, path=None):
894
 
        """See Tree.iter_children."""
895
 
        entry = self.iter_entries_by_dir([file_id]).next()[1]
896
 
        for child in getattr(entry, 'children', {}).itervalues():
897
 
            yield child.file_id
 
831
        return self.get_file(self._inventory.path2id(path), path)
898
832
 
899
833
 
900
834
def find_ids_across_trees(filenames, trees, require_versioned=True):
1055
989
            if (self.source.get_symlink_target(file_id) !=
1056
990
                self.target.get_symlink_target(file_id)):
1057
991
                changed_content = True
1058
 
        elif source_kind == 'tree-reference':
1059
 
            if (self.source.get_reference_revision(file_id, source_path)
1060
 
                != self.target.get_reference_revision(file_id, target_path)):
 
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)):
1061
999
                    changed_content = True
1062
1000
        parent = (source_parent, target_parent)
1063
1001
        name = (source_name, target_name)
1278
1216
        :param file_id: The file_id to lookup.
1279
1217
        """
1280
1218
        try:
1281
 
            inventory = tree.root_inventory
 
1219
            inventory = tree.inventory
1282
1220
        except NotImplementedError:
1283
1221
            # No inventory available.
1284
1222
            try:
1359
1297
                        if old_entry is None:
1360
1298
                            # Reusing a discarded change.
1361
1299
                            old_entry = self._get_entry(self.source, file_id)
1362
 
                        precise_file_ids.update(
1363
 
                                self.source.iter_children(file_id))
 
1300
                        for child in old_entry.children.values():
 
1301
                            precise_file_ids.add(child.file_id)
1364
1302
                    changed_file_ids.add(result[0])
1365
1303
                    yield result
1366
1304
 
1509
1447
            return (None, None)
1510
1448
        else:
1511
1449
            self._out_of_order_processed.add(file_id)
1512
 
            cur_ie = other_tree.root_inventory[file_id]
 
1450
            cur_ie = other_tree.inventory[file_id]
1513
1451
            return (cur_path, cur_ie)
1514
1452
 
1515
1453
    def iter_all(self):