~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tree.py

  • Committer: Samuel Bronson
  • Date: 2012-08-30 20:36:18 UTC
  • mto: (6015.57.3 2.4)
  • mto: This revision was merged to the branch mainline in revision 6558.
  • Revision ID: naesten@gmail.com-20120830203618-y2dzw91nqpvpgxvx
Update INSTALL for switch to Python 2.6 and up.

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
37
35
    rules,
38
36
    trace,
39
37
    )
40
 
from bzrlib.i18n import gettext
41
38
""")
42
39
 
43
40
from bzrlib.decorators import needs_read_lock
61
58
    trees or versioned trees.
62
59
    """
63
60
 
64
 
    def has_versioned_directories(self):
65
 
        """Whether this tree can contain explicitly versioned directories.
66
 
 
67
 
        This defaults to True, but some implementations may want to override
68
 
        it.
69
 
        """
70
 
        return True
71
 
 
72
61
    def changes_from(self, other, want_unchanged=False, specific_files=None,
73
62
        extra_trees=None, require_versioned=False, include_root=False,
74
63
        want_unversioned=False):
288
277
 
289
278
        :param file_id: The file_id of the file.
290
279
        :param path: The path of the file.
291
 
 
292
280
        If both file_id and path are supplied, an implementation may use
293
281
        either one.
294
 
 
295
 
        :returns: A single byte string for the whole file.
296
282
        """
297
283
        my_file = self.get_file(file_id, path)
298
284
        try:
311
297
        """
312
298
        return osutils.split_lines(self.get_file_text(file_id, path))
313
299
 
314
 
    def get_file_verifier(self, file_id, path=None, stat_value=None):
315
 
        """Return a verifier for a file.
316
 
 
317
 
        The default implementation returns a sha1.
318
 
 
319
 
        :param file_id: The handle for this file.
320
 
        :param path: The path that this file can be found at.
321
 
            These must point to the same object.
322
 
        :param stat_value: Optional stat value for the object
323
 
        :return: Tuple with verifier name and verifier data
324
 
        """
325
 
        return ("SHA1", self.get_file_sha1(file_id, path=path,
326
 
            stat_value=stat_value))
327
 
 
328
300
    def get_file_sha1(self, file_id, path=None, stat_value=None):
329
301
        """Return the SHA1 file for a file.
330
302
 
331
 
        :note: callers should use get_file_verifier instead
332
 
            where possible, as the underlying repository implementation may
333
 
            have quicker access to a non-sha1 verifier.
334
 
 
335
303
        :param file_id: The handle for this file.
336
304
        :param path: The path that this file can be found at.
337
305
            These must point to the same object.
357
325
        """
358
326
        raise NotImplementedError(self.get_file_size)
359
327
 
 
328
    def get_file_by_path(self, path):
 
329
        raise NotImplementedError(self.get_file_by_path)
 
330
 
360
331
    def is_executable(self, file_id, path=None):
361
332
        """Check if a file is executable.
362
333
 
631
602
        prefs = self.iter_search_rules([path], filter_pref_names).next()
632
603
        stk = filters._get_filter_stack_for(prefs)
633
604
        if 'filters' in debug.debug_flags:
634
 
            trace.note(gettext("*** {0} content-filter: {1} => {2!r}").format(path,prefs,stk))
 
605
            trace.note("*** %s content-filter: %s => %r" % (path,prefs,stk))
635
606
        return stk
636
607
 
637
608
    def _content_filter_stack_provider(self):
774
745
    inventory = property(_get_inventory,
775
746
                         doc="Inventory of this Tree")
776
747
 
777
 
    def _unpack_file_id(self, file_id):
778
 
        """Find the inventory and inventory file id for a tree file id.
779
 
 
780
 
        :param file_id: The tree file id, as bytestring or tuple
781
 
        :return: Inventory and inventory file id
782
 
        """
783
 
        if isinstance(file_id, tuple):
784
 
            if len(file_id) != 1:
785
 
                raise ValueError("nested trees not yet supported: %r" % file_id)
786
 
            file_id = file_id[0]
787
 
        return self.inventory, file_id
788
 
 
789
748
    @needs_read_lock
790
749
    def path2id(self, path):
791
750
        """Return the id for path in this tree."""
792
 
        return self._path2inv_file_id(path)[1]
793
 
 
794
 
    def _path2inv_file_id(self, path):
795
 
        """Lookup a inventory and inventory file id by path.
796
 
 
797
 
        :param path: Path to look up
798
 
        :return: tuple with inventory and inventory file id
799
 
        """
800
 
        return self.inventory, self.inventory.path2id(path)
 
751
        return self._inventory.path2id(path)
801
752
 
802
753
    def id2path(self, file_id):
803
754
        """Return the path for a file id.
804
755
 
805
756
        :raises NoSuchId:
806
757
        """
807
 
        inventory, file_id = self._unpack_file_id(file_id)
808
 
        return inventory.id2path(file_id)
 
758
        return self.inventory.id2path(file_id)
809
759
 
810
760
    def has_id(self, file_id):
811
 
        inventory, file_id = self._unpack_file_id(file_id)
812
 
        return inventory.has_id(file_id)
 
761
        return self.inventory.has_id(file_id)
813
762
 
814
763
    def has_or_had_id(self, file_id):
815
 
        inventory, file_id = self._unpack_file_id(file_id)
816
 
        return inventory.has_id(file_id)
 
764
        return self.inventory.has_id(file_id)
817
765
 
818
766
    def all_file_ids(self):
819
 
        return set(
820
 
            [entry.file_id for path, entry in self.iter_entries_by_dir()])
 
767
        return set(self.inventory)
821
768
 
822
769
    @deprecated_method(deprecated_in((2, 4, 0)))
823
770
    def __iter__(self):
824
 
        return iter(self.all_file_ids())
 
771
        return iter(self.inventory)
825
772
 
826
773
    def filter_unversioned_files(self, paths):
827
774
        """Filter out paths that are versioned.
831
778
        # NB: we specifically *don't* call self.has_filename, because for
832
779
        # WorkingTrees that can indicate files that exist on disk but that
833
780
        # are not versioned.
834
 
        return set((p for p in paths if self.path2id(p) is None))
 
781
        pred = self.inventory.has_filename
 
782
        return set((p for p in paths if not pred(p)))
835
783
 
836
784
    @needs_read_lock
837
785
    def iter_entries_by_dir(self, specific_file_ids=None, yield_parents=False):
846
794
            down to specific_file_ids that have been requested. This has no
847
795
            impact if specific_file_ids is None.
848
796
        """
849
 
        if specific_file_ids is None:
850
 
            inventory_file_ids = None
851
 
        else:
852
 
            inventory_file_ids = []
853
 
            for tree_file_id in specific_file_ids:
854
 
                inventory, inv_file_id = self._unpack_file_id(tree_file_id)
855
 
                if not inventory is self.inventory: # for now
856
 
                    raise AssertionError("%r != %r" % (
857
 
                        inventory, self.inventory))
858
 
                inventory_file_ids.append(inv_file_id)
859
797
        return self.inventory.iter_entries_by_dir(
860
 
            specific_file_ids=inventory_file_ids, yield_parents=yield_parents)
 
798
            specific_file_ids=specific_file_ids, yield_parents=yield_parents)
861
799
 
862
 
    @deprecated_method(deprecated_in((2, 5, 0)))
863
800
    def get_file_by_path(self, path):
864
 
        return self.get_file(self.path2id(path), path)
 
801
        return self.get_file(self._inventory.path2id(path), path)
865
802
 
866
803
 
867
804
def find_ids_across_trees(filenames, trees, require_versioned=True):
1015
952
        if source_kind != target_kind:
1016
953
            changed_content = True
1017
954
        elif source_kind == 'file':
1018
 
            if not self.file_content_matches(file_id, file_id, source_path,
1019
 
                    target_path, source_stat, target_stat):
 
955
            if (self.source.get_file_sha1(file_id, source_path, source_stat) !=
 
956
                self.target.get_file_sha1(file_id, target_path, target_stat)):
1020
957
                changed_content = True
1021
958
        elif source_kind == 'symlink':
1022
959
            if (self.source.get_symlink_target(file_id) !=
1335
1272
                    changed_file_ids.add(result[0])
1336
1273
                    yield result
1337
1274
 
1338
 
    @needs_read_lock
1339
 
    def file_content_matches(self, source_file_id, target_file_id,
1340
 
            source_path=None, target_path=None, source_stat=None, target_stat=None):
1341
 
        """Check if two files are the same in the source and target trees.
1342
 
 
1343
 
        This only checks that the contents of the files are the same,
1344
 
        it does not touch anything else.
1345
 
 
1346
 
        :param source_file_id: File id of the file in the source tree
1347
 
        :param target_file_id: File id of the file in the target tree
1348
 
        :param source_path: Path of the file in the source tree
1349
 
        :param target_path: Path of the file in the target tree
1350
 
        :param source_stat: Optional stat value of the file in the source tree
1351
 
        :param target_stat: Optional stat value of the file in the target tree
1352
 
        :return: Boolean indicating whether the files have the same contents
1353
 
        """
1354
 
        source_verifier_kind, source_verifier_data = self.source.get_file_verifier(
1355
 
            source_file_id, source_path, source_stat)
1356
 
        target_verifier_kind, target_verifier_data = self.target.get_file_verifier(
1357
 
            target_file_id, target_path, target_stat)
1358
 
        if source_verifier_kind == target_verifier_kind:
1359
 
            return (source_verifier_data == target_verifier_data)
1360
 
        # Fall back to SHA1 for now
1361
 
        if source_verifier_kind != "SHA1":
1362
 
            source_sha1 = self.source.get_file_sha1(source_file_id,
1363
 
                    source_path, source_stat)
1364
 
        else:
1365
 
            source_sha1 = source_verifier_data
1366
 
        if target_verifier_kind != "SHA1":
1367
 
            target_sha1 = self.target.get_file_sha1(target_file_id,
1368
 
                    target_path, target_stat)
1369
 
        else:
1370
 
            target_sha1 = target_verifier_data
1371
 
        return (source_sha1 == target_sha1)
1372
1275
 
1373
1276
InterTree.register_optimiser(InterTree)
1374
1277