~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tree.py

  • Committer: Martin Pool
  • Date: 2009-03-03 03:01:49 UTC
  • mfrom: (4070 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4073.
  • Revision ID: mbp@sourcefrog.net-20090303030149-8p8o8hszdtqa7w8f
merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 Canonical Ltd
 
1
# Copyright (C) 2005, 2009 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
45
45
    """Abstract file tree.
46
46
 
47
47
    There are several subclasses:
48
 
    
 
48
 
49
49
    * `WorkingTree` exists as files on disk editable by the user.
50
50
 
51
51
    * `RevisionTree` is a tree as recorded at some point in the past.
60
60
    Trees can be compared, etc, regardless of whether they are working
61
61
    trees or versioned trees.
62
62
    """
63
 
    
 
63
 
64
64
    def changes_from(self, other, want_unchanged=False, specific_files=None,
65
65
        extra_trees=None, require_versioned=False, include_root=False,
66
66
        want_unversioned=False):
80
80
            a PathsNotVersionedError will be thrown.
81
81
        :param want_unversioned: Scan for unversioned paths.
82
82
 
83
 
        The comparison will be performed by an InterTree object looked up on 
 
83
        The comparison will be performed by an InterTree object looked up on
84
84
        self and other.
85
85
        """
86
86
        # Martin observes that Tree.changes_from returns a TreeDelta and this
105
105
        intertree = InterTree.get(from_tree, self)
106
106
        return intertree.iter_changes(include_unchanged, specific_files, pb,
107
107
            extra_trees, require_versioned, want_unversioned=want_unversioned)
108
 
    
 
108
 
109
109
    def conflicts(self):
110
110
        """Get a list of the conflicts in the tree.
111
111
 
118
118
        return []
119
119
 
120
120
    def get_parent_ids(self):
121
 
        """Get the parent ids for this tree. 
 
121
        """Get the parent ids for this tree.
122
122
 
123
123
        :return: a list of parent ids. [] is returned to indicate
124
124
        a tree with no parents.
125
125
        :raises: BzrError if the parents are not known.
126
126
        """
127
127
        raise NotImplementedError(self.get_parent_ids)
128
 
    
 
128
 
129
129
    def has_filename(self, filename):
130
130
        """True if the tree has given filename."""
131
131
        raise NotImplementedError(self.has_filename)
165
165
 
166
166
    def is_control_filename(self, filename):
167
167
        """True if filename is the name of a control file in this tree.
168
 
        
 
168
 
169
169
        :param filename: A filename within the tree. This is a relative path
170
170
        from the root of this tree.
171
171
 
222
222
 
223
223
    def path_content_summary(self, path):
224
224
        """Get a summary of the information about path.
225
 
        
 
225
 
226
226
        :param path: A relative path within the tree.
227
227
        :return: A tuple containing kind, size, exec, sha1-or-link.
228
228
            Kind is always present (see tree.kind()).
255
255
 
256
256
    def _get_inventory(self):
257
257
        return self._inventory
258
 
    
 
258
 
259
259
    def get_file(self, file_id, path=None):
260
260
        """Return a file object for the file file_id in the tree.
261
 
        
 
261
 
262
262
        If both file_id and path are defined, it is implementation defined as
263
263
        to which one is used.
264
264
        """
500
500
 
501
501
    def _check_retrieved(self, ie, f):
502
502
        if not __debug__:
503
 
            return  
 
503
            return
504
504
        fp = fingerprint_file(f)
505
505
        f.seek(0)
506
 
        
 
506
 
507
507
        if ie.text_size is not None:
508
508
            if ie.text_size != fp['size']:
509
509
                raise BzrError("mismatched size for file %r in %r" % (ie.file_id, self._store),
524
524
 
525
525
    def paths2ids(self, paths, trees=[], require_versioned=True):
526
526
        """Return all the ids that can be reached by walking from paths.
527
 
        
 
527
 
528
528
        Each path is looked up in this tree and any extras provided in
529
529
        trees, and this is repeated recursively: the children in an extra tree
530
530
        of a directory that has been renamed under a provided path in this tree
560
560
 
561
561
        The intention of this method is to allow access to possibly cached
562
562
        tree data. Implementors of this method should raise NoSuchRevision if
563
 
        the tree is not locally available, even if they could obtain the 
564
 
        tree via a repository or some other means. Callers are responsible 
 
563
        the tree is not locally available, even if they could obtain the
 
564
        tree via a repository or some other means. Callers are responsible
565
565
        for finding the ultimate source for a revision tree.
566
566
 
567
567
        :param revision_id: The revision_id of the requested tree.
572
572
 
573
573
    def unknowns(self):
574
574
        """What files are present in this tree and unknown.
575
 
        
 
575
 
576
576
        :return: an iterator over the unknown files.
577
577
        """
578
578
        return iter([])
586
586
        :return: set of paths.
587
587
        """
588
588
        # NB: we specifically *don't* call self.has_filename, because for
589
 
        # WorkingTrees that can indicate files that exist on disk but that 
 
589
        # WorkingTrees that can indicate files that exist on disk but that
590
590
        # are not versioned.
591
591
        pred = self.inventory.has_filename
592
592
        return set((p for p in paths if not pred(p)))
597
597
        This yields all the data about the contents of a directory at a time.
598
598
        After each directory has been yielded, if the caller has mutated the
599
599
        list to exclude some directories, they are then not descended into.
600
 
        
 
600
 
601
601
        The data yielded is of the form:
602
602
        ((directory-relpath, directory-path-from-root, directory-fileid),
603
 
        [(relpath, basename, kind, lstat, path_from_tree_root, file_id, 
 
603
        [(relpath, basename, kind, lstat, path_from_tree_root, file_id,
604
604
          versioned_kind), ...]),
605
605
         - directory-relpath is the containing dirs relpath from prefix
606
606
         - directory-path-from-root is the containing dirs path from /
613
613
         - lstat is the stat data *if* the file was statted.
614
614
         - path_from_tree_root is the path from the root of the tree.
615
615
         - file_id is the file_id if the entry is versioned.
616
 
         - versioned_kind is the kind of the file as last recorded in the 
 
616
         - versioned_kind is the kind of the file as last recorded in the
617
617
           versioning system. If 'unknown' the file is not versioned.
618
618
        One of 'kind' and 'versioned_kind' must not be 'unknown'.
619
619
 
706
706
 
707
707
    return 'wtf?'
708
708
 
709
 
    
 
709
 
710
710
@deprecated_function(deprecated_in((1, 9, 0)))
711
711
def find_renames(old_inv, new_inv):
712
712
    for file_id in old_inv:
720
720
 
721
721
def find_ids_across_trees(filenames, trees, require_versioned=True):
722
722
    """Find the ids corresponding to specified filenames.
723
 
    
 
723
 
724
724
    All matches in all trees will be used, and all children of matched
725
725
    directories will be used.
726
726
 
740
740
 
741
741
def _find_ids_across_trees(filenames, trees, require_versioned):
742
742
    """Find the ids corresponding to specified filenames.
743
 
    
 
743
 
744
744
    All matches in all trees will be used, but subdirectories are not scanned.
745
745
 
746
746
    :param filenames: The filenames to find file_ids for
767
767
 
768
768
def _find_children_across_trees(specified_ids, trees):
769
769
    """Return a set including specified ids and their children.
770
 
    
 
770
 
771
771
    All matches in all trees will be used.
772
772
 
773
773
    :param trees: The trees to find file_ids within
774
 
    :return: a set containing all specified ids and their children 
 
774
    :return: a set containing all specified ids and their children
775
775
    """
776
776
    interesting_ids = set(specified_ids)
777
777
    pending = interesting_ids
901
901
            specific_file_ids=specific_file_ids))
902
902
        num_entries = len(from_entries_by_dir) + len(to_entries_by_dir)
903
903
        entry_count = 0
904
 
        # the unversioned path lookup only occurs on real trees - where there 
 
904
        # the unversioned path lookup only occurs on real trees - where there
905
905
        # can be extras. So the fake_entry is solely used to look up
906
906
        # executable it values when execute is not supported.
907
907
        fake_entry = InventoryFile('unused', 'unused', 'unused')
955
955
                elif from_kind == 'tree-reference':
956
956
                    if (self.source.get_reference_revision(file_id, from_path)
957
957
                        != self.target.get_reference_revision(file_id, to_path)):
958
 
                        changed_content = True 
 
958
                        changed_content = True
959
959
            parent = (from_parent, to_entry.parent_id)
960
960
            name = (from_name, to_entry.name)
961
961
            executable = (from_executable, to_executable)
962
962
            if pb is not None:
963
963
                pb.update('comparing files', entry_count, num_entries)
964
964
            if (changed_content is not False or versioned[0] != versioned[1]
965
 
                or parent[0] != parent[1] or name[0] != name[1] or 
 
965
                or parent[0] != parent[1] or name[0] != name[1] or
966
966
                executable[0] != executable[1] or include_unchanged):
967
967
                yield (file_id, (from_path, to_path), changed_content,
968
968
                    versioned, parent, name, kind, executable)
1137
1137
 
1138
1138
    def _walk_master_tree(self):
1139
1139
        """First pass, walk all trees in lock-step.
1140
 
        
 
1140
 
1141
1141
        When we are done, all nodes in the master_tree will have been
1142
1142
        processed. _other_walkers, _other_entries, and _others_extra will be
1143
1143
        set on 'self' for future processing.