/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tree.py

merge bzr.dev r4042

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
    symbol_versioning,
34
34
    )
35
35
from bzrlib.decorators import needs_read_lock
36
 
from bzrlib.errors import BzrError, BzrCheckError
 
36
from bzrlib.errors import BzrError, BzrCheckError, NoSuchId
37
37
from bzrlib import errors
38
38
from bzrlib.inventory import Inventory, InventoryFile
39
39
from bzrlib.inter import InterObject
47
47
    """Abstract file tree.
48
48
 
49
49
    There are several subclasses:
50
 
    
 
50
 
51
51
    * `WorkingTree` exists as files on disk editable by the user.
52
52
 
53
53
    * `RevisionTree` is a tree as recorded at some point in the past.
62
62
    Trees can be compared, etc, regardless of whether they are working
63
63
    trees or versioned trees.
64
64
    """
65
 
    
 
65
 
66
66
    def changes_from(self, other, want_unchanged=False, specific_files=None,
67
67
        extra_trees=None, require_versioned=False, include_root=False,
68
68
        want_unversioned=False):
82
82
            a PathsNotVersionedError will be thrown.
83
83
        :param want_unversioned: Scan for unversioned paths.
84
84
 
85
 
        The comparison will be performed by an InterTree object looked up on 
 
85
        The comparison will be performed by an InterTree object looked up on
86
86
        self and other.
87
87
        """
88
88
        # Martin observes that Tree.changes_from returns a TreeDelta and this
107
107
        intertree = InterTree.get(from_tree, self)
108
108
        return intertree.iter_changes(include_unchanged, specific_files, pb,
109
109
            extra_trees, require_versioned, want_unversioned=want_unversioned)
110
 
    
 
110
 
111
111
    def conflicts(self):
112
112
        """Get a list of the conflicts in the tree.
113
113
 
120
120
        return []
121
121
 
122
122
    def get_parent_ids(self):
123
 
        """Get the parent ids for this tree. 
 
123
        """Get the parent ids for this tree.
124
124
 
125
125
        :return: a list of parent ids. [] is returned to indicate
126
126
        a tree with no parents.
127
127
        :raises: BzrError if the parents are not known.
128
128
        """
129
129
        raise NotImplementedError(self.get_parent_ids)
130
 
    
 
130
 
131
131
    def has_filename(self, filename):
132
132
        """True if the tree has given filename."""
133
133
        raise NotImplementedError(self.has_filename)
167
167
 
168
168
    def is_control_filename(self, filename):
169
169
        """True if filename is the name of a control file in this tree.
170
 
        
 
170
 
171
171
        :param filename: A filename within the tree. This is a relative path
172
172
        from the root of this tree.
173
173
 
224
224
 
225
225
    def path_content_summary(self, path):
226
226
        """Get a summary of the information about path.
227
 
        
 
227
 
228
228
        :param path: A relative path within the tree.
229
229
        :return: A tuple containing kind, size, exec, sha1-or-link.
230
230
            Kind is always present (see tree.kind()).
257
257
 
258
258
    def _get_inventory(self):
259
259
        return self._inventory
260
 
    
 
260
 
261
261
    def get_file(self, file_id, path=None):
262
262
        """Return a file object for the file file_id in the tree.
263
 
        
 
263
 
264
264
        If both file_id and path are defined, it is implementation defined as
265
265
        to which one is used.
266
266
        """
347
347
        """
348
348
        raise NotImplementedError(self.get_symlink_target)
349
349
 
 
350
    def get_canonical_inventory_paths(self, paths):
 
351
        """Like get_canonical_inventory_path() but works on multiple items.
 
352
 
 
353
        :param paths: A sequence of paths relative to the root of the tree.
 
354
        :return: A list of paths, with each item the corresponding input path
 
355
        adjusted to account for existing elements that match case
 
356
        insensitively.
 
357
        """
 
358
        return list(self._yield_canonical_inventory_paths(paths))
 
359
 
 
360
    def get_canonical_inventory_path(self, path):
 
361
        """Returns the first inventory item that case-insensitively matches path.
 
362
 
 
363
        If a path matches exactly, it is returned. If no path matches exactly
 
364
        but more than one path matches case-insensitively, it is implementation
 
365
        defined which is returned.
 
366
 
 
367
        If no path matches case-insensitively, the input path is returned, but
 
368
        with as many path entries that do exist changed to their canonical
 
369
        form.
 
370
 
 
371
        If you need to resolve many names from the same tree, you should
 
372
        use get_canonical_inventory_paths() to avoid O(N) behaviour.
 
373
 
 
374
        :param path: A paths relative to the root of the tree.
 
375
        :return: The input path adjusted to account for existing elements
 
376
        that match case insensitively.
 
377
        """
 
378
        return self._yield_canonical_inventory_paths([path]).next()
 
379
 
 
380
    def _yield_canonical_inventory_paths(self, paths):
 
381
        for path in paths:
 
382
            # First, if the path as specified exists exactly, just use it.
 
383
            if self.path2id(path) is not None:
 
384
                yield path
 
385
                continue
 
386
            # go walkin...
 
387
            cur_id = self.get_root_id()
 
388
            cur_path = ''
 
389
            bit_iter = iter(path.split("/"))
 
390
            for elt in bit_iter:
 
391
                lelt = elt.lower()
 
392
                for child in self.iter_children(cur_id):
 
393
                    try:
 
394
                        child_base = os.path.basename(self.id2path(child))
 
395
                        if child_base.lower() == lelt:
 
396
                            cur_id = child
 
397
                            cur_path = osutils.pathjoin(cur_path, child_base)
 
398
                            break
 
399
                    except NoSuchId:
 
400
                        # before a change is committed we can see this error...
 
401
                        continue
 
402
                else:
 
403
                    # got to the end of this directory and no entries matched.
 
404
                    # Return what matched so far, plus the rest as specified.
 
405
                    cur_path = osutils.pathjoin(cur_path, elt, *list(bit_iter))
 
406
                    break
 
407
            yield cur_path
 
408
        # all done.
 
409
 
350
410
    def get_root_id(self):
351
411
        """Return the file_id for the root of this tree."""
352
412
        raise NotImplementedError(self.get_root_id)
442
502
 
443
503
    def _check_retrieved(self, ie, f):
444
504
        if not __debug__:
445
 
            return  
 
505
            return
446
506
        fp = fingerprint_file(f)
447
507
        f.seek(0)
448
 
        
 
508
 
449
509
        if ie.text_size is not None:
450
510
            if ie.text_size != fp['size']:
451
511
                raise BzrError("mismatched size for file %r in %r" % (ie.file_id, self._store),
466
526
 
467
527
    def paths2ids(self, paths, trees=[], require_versioned=True):
468
528
        """Return all the ids that can be reached by walking from paths.
469
 
        
 
529
 
470
530
        Each path is looked up in this tree and any extras provided in
471
531
        trees, and this is repeated recursively: the children in an extra tree
472
532
        of a directory that has been renamed under a provided path in this tree
502
562
 
503
563
        The intention of this method is to allow access to possibly cached
504
564
        tree data. Implementors of this method should raise NoSuchRevision if
505
 
        the tree is not locally available, even if they could obtain the 
506
 
        tree via a repository or some other means. Callers are responsible 
 
565
        the tree is not locally available, even if they could obtain the
 
566
        tree via a repository or some other means. Callers are responsible
507
567
        for finding the ultimate source for a revision tree.
508
568
 
509
569
        :param revision_id: The revision_id of the requested tree.
514
574
 
515
575
    def unknowns(self):
516
576
        """What files are present in this tree and unknown.
517
 
        
 
577
 
518
578
        :return: an iterator over the unknown files.
519
579
        """
520
580
        return iter([])
528
588
        :return: set of paths.
529
589
        """
530
590
        # NB: we specifically *don't* call self.has_filename, because for
531
 
        # WorkingTrees that can indicate files that exist on disk but that 
 
591
        # WorkingTrees that can indicate files that exist on disk but that
532
592
        # are not versioned.
533
593
        pred = self.inventory.has_filename
534
594
        return set((p for p in paths if not pred(p)))
539
599
        This yields all the data about the contents of a directory at a time.
540
600
        After each directory has been yielded, if the caller has mutated the
541
601
        list to exclude some directories, they are then not descended into.
542
 
        
 
602
 
543
603
        The data yielded is of the form:
544
604
        ((directory-relpath, directory-path-from-root, directory-fileid),
545
 
        [(relpath, basename, kind, lstat, path_from_tree_root, file_id, 
 
605
        [(relpath, basename, kind, lstat, path_from_tree_root, file_id,
546
606
          versioned_kind), ...]),
547
607
         - directory-relpath is the containing dirs relpath from prefix
548
608
         - directory-path-from-root is the containing dirs path from /
555
615
         - lstat is the stat data *if* the file was statted.
556
616
         - path_from_tree_root is the path from the root of the tree.
557
617
         - file_id is the file_id if the entry is versioned.
558
 
         - versioned_kind is the kind of the file as last recorded in the 
 
618
         - versioned_kind is the kind of the file as last recorded in the
559
619
           versioning system. If 'unknown' the file is not versioned.
560
620
        One of 'kind' and 'versioned_kind' must not be 'unknown'.
561
621
 
571
631
 
572
632
    def _content_filter_stack(self, path=None, file_id=None):
573
633
        """The stack of content filters for a path if filtering is supported.
574
 
 
 
634
 
575
635
        Readers will be applied in first-to-last order.
576
636
        Writers will be applied in last-to-first order.
577
637
        Either the path or the file-id needs to be provided.
655
715
 
656
716
    def list_files(self, include_root=False):
657
717
        return iter([])
658
 
    
 
718
 
659
719
    def __contains__(self, file_id):
660
720
        return (file_id in self._inventory)
661
721
 
715
775
 
716
776
    return 'wtf?'
717
777
 
718
 
    
 
778
 
719
779
@deprecated_function(deprecated_in((1, 9, 0)))
720
780
def find_renames(old_inv, new_inv):
721
781
    for file_id in old_inv:
729
789
 
730
790
def find_ids_across_trees(filenames, trees, require_versioned=True):
731
791
    """Find the ids corresponding to specified filenames.
732
 
    
 
792
 
733
793
    All matches in all trees will be used, and all children of matched
734
794
    directories will be used.
735
795
 
749
809
 
750
810
def _find_ids_across_trees(filenames, trees, require_versioned):
751
811
    """Find the ids corresponding to specified filenames.
752
 
    
 
812
 
753
813
    All matches in all trees will be used, but subdirectories are not scanned.
754
814
 
755
815
    :param filenames: The filenames to find file_ids for
776
836
 
777
837
def _find_children_across_trees(specified_ids, trees):
778
838
    """Return a set including specified ids and their children.
779
 
    
 
839
 
780
840
    All matches in all trees will be used.
781
841
 
782
842
    :param trees: The trees to find file_ids within
783
 
    :return: a set containing all specified ids and their children 
 
843
    :return: a set containing all specified ids and their children
784
844
    """
785
845
    interesting_ids = set(specified_ids)
786
846
    pending = interesting_ids
910
970
            specific_file_ids=specific_file_ids))
911
971
        num_entries = len(from_entries_by_dir) + len(to_entries_by_dir)
912
972
        entry_count = 0
913
 
        # the unversioned path lookup only occurs on real trees - where there 
 
973
        # the unversioned path lookup only occurs on real trees - where there
914
974
        # can be extras. So the fake_entry is solely used to look up
915
975
        # executable it values when execute is not supported.
916
976
        fake_entry = InventoryFile('unused', 'unused', 'unused')
960
1020
                elif from_kind == 'tree-reference':
961
1021
                    if (self.source.get_reference_revision(file_id, from_path)
962
1022
                        != self.target.get_reference_revision(file_id, to_path)):
963
 
                        changed_content = True 
 
1023
                        changed_content = True
964
1024
            parent = (from_parent, to_entry.parent_id)
965
1025
            name = (from_name, to_entry.name)
966
1026
            executable = (from_executable, to_executable)
967
1027
            if pb is not None:
968
1028
                pb.update('comparing files', entry_count, num_entries)
969
1029
            if (changed_content is not False or versioned[0] != versioned[1]
970
 
                or parent[0] != parent[1] or name[0] != name[1] or 
 
1030
                or parent[0] != parent[1] or name[0] != name[1] or
971
1031
                executable[0] != executable[1] or include_unchanged):
972
1032
                yield (file_id, (from_path, to_path), changed_content,
973
1033
                    versioned, parent, name, kind, executable)
1142
1202
 
1143
1203
    def _walk_master_tree(self):
1144
1204
        """First pass, walk all trees in lock-step.
1145
 
        
 
1205
 
1146
1206
        When we are done, all nodes in the master_tree will have been
1147
1207
        processed. _other_walkers, _other_entries, and _others_extra will be
1148
1208
        set on 'self' for future processing.