~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: John Arbash Meinel
  • Date: 2011-05-11 11:35:28 UTC
  • mto: This revision was merged to the branch mainline in revision 5851.
  • Revision ID: john@arbash-meinel.com-20110511113528-qepibuwxicjrbb2h
Break compatibility with python <2.6.

This includes auditing the code for places where we were doing
explicit 'sys.version' checks and removing them as appropriate.

Show diffs side-by-side

added added

removed removed

Lines of Context:
230
230
        """True if filename is the name of a control file in this tree.
231
231
 
232
232
        :param filename: A filename within the tree. This is a relative path
233
 
            from the root of this tree.
 
233
        from the root of this tree.
234
234
 
235
235
        This is true IF and ONLY IF the filename is part of the meta data
236
236
        that bzr controls in this tree. I.E. a random .bzr directory placed
268
268
        self._control_files.break_lock()
269
269
        self.branch.break_lock()
270
270
 
 
271
    def _get_check_refs(self):
 
272
        """Return the references needed to perform a check of this tree.
 
273
        
 
274
        The default implementation returns no refs, and is only suitable for
 
275
        trees that have no local caching and can commit on ghosts at any time.
 
276
 
 
277
        :seealso: bzrlib.check for details about check_refs.
 
278
        """
 
279
        return []
 
280
 
271
281
    def requires_rich_root(self):
272
282
        return self._format.requires_rich_root
273
283
 
496
506
        finally:
497
507
            file.close()
498
508
 
 
509
    def _get_ancestors(self, default_revision):
 
510
        ancestors = set([default_revision])
 
511
        for parent_id in self.get_parent_ids():
 
512
            ancestors.update(self.branch.repository.get_ancestry(
 
513
                             parent_id, topo_sorted=False))
 
514
        return ancestors
 
515
 
499
516
    def get_parent_ids(self):
500
517
        """See Tree.get_parent_ids.
501
518
 
595
612
            else:
596
613
                return None
597
614
 
 
615
    def get_file_sha1(self, file_id, path=None, stat_value=None):
 
616
        # FIXME: Shouldn't this be in Tree?
 
617
        raise NotImplementedError(self.get_file_sha1)
 
618
 
598
619
    @needs_tree_write_lock
599
620
    def _gather_kinds(self, files, kinds):
600
621
        """See MutableTree._gather_kinds."""
615
636
        and setting the list to its value plus revision_id.
616
637
 
617
638
        :param revision_id: The revision id to add to the parent list. It may
618
 
            be a ghost revision as long as its not the first parent to be
619
 
            added, or the allow_leftmost_as_ghost parameter is set True.
 
639
        be a ghost revision as long as its not the first parent to be added,
 
640
        or the allow_leftmost_as_ghost parameter is set True.
620
641
        :param allow_leftmost_as_ghost: Allow the first parent to be a ghost.
621
642
        """
622
643
        parents = self.get_parent_ids() + [revision_id]
852
873
        self.add(path, file_id, 'directory')
853
874
        return file_id
854
875
 
855
 
    def get_symlink_target(self, file_id, path=None):
856
 
        if path is not None:
857
 
            abspath = self.abspath(path)
858
 
        else:
859
 
            abspath = self.id2abspath(file_id)
 
876
    def get_symlink_target(self, file_id):
 
877
        abspath = self.id2abspath(file_id)
860
878
        target = osutils.readlink(abspath)
861
879
        return target
862
880
 
962
980
        file and change the file_id. That is the normal mode. Second, it can
963
981
        only change the file_id without touching any physical file.
964
982
 
965
 
        rename_one uses the second mode if 'after == True' and 'to_rel' is
966
 
        either not versioned or newly added, and present in the working tree.
 
983
        rename_one uses the second mode if 'after == True' and 'to_rel' is not
 
984
        versioned but present in the working tree.
967
985
 
968
986
        rename_one uses the second mode if 'after == False' and 'from_rel' is
969
987
        versioned but no longer in the working tree, and 'to_rel' is not
1014
1032
            new_revision_info = self.branch.last_revision_info()
1015
1033
            if new_revision_info != old_revision_info:
1016
1034
                repository = self.branch.repository
1017
 
                if repository._format.fast_deltas:
1018
 
                    parent_ids = self.get_parent_ids()
1019
 
                    if parent_ids:
1020
 
                        basis_id = parent_ids[0]
1021
 
                        basis_tree = repository.revision_tree(basis_id)
1022
1035
                basis_tree.lock_read()
1023
1036
                try:
1024
1037
                    new_basis_tree = self.branch.basis_tree()
1374
1387
    def revert(self, filenames=None, old_tree=None, backups=True,
1375
1388
               pb=None, report_changes=False):
1376
1389
        from bzrlib.conflicts import resolve
 
1390
        if filenames == []:
 
1391
            filenames = None
 
1392
            symbol_versioning.warn('Using [] to revert all files is deprecated'
 
1393
                ' as of bzr 0.91.  Please use None (the default) instead.',
 
1394
                DeprecationWarning, stacklevel=2)
1377
1395
        if old_tree is None:
1378
1396
            basis_tree = self.basis_tree()
1379
1397
            basis_tree.lock_read()
1462
1480
        - Restore the wt.basis->wt.state changes.
1463
1481
 
1464
1482
        There isn't a single operation at the moment to do that, so we:
1465
 
 
1466
1483
        - Merge current state -> basis tree of the master w.r.t. the old tree
1467
1484
          basis.
1468
1485
        - Do a 'normal' merge of the old branch basis if it is relevant.
1723
1740
    def _walkdirs(self, prefix=""):
1724
1741
        """Walk the directories of this tree.
1725
1742
 
1726
 
        :param prefix: is used as the directrory to start with.
1727
 
        :returns: a generator which yields items in the form::
1728
 
 
1729
 
            ((curren_directory_path, fileid),
1730
 
             [(file1_path, file1_name, file1_kind, None, file1_id,
1731
 
               file1_kind), ... ])
 
1743
           :prefix: is used as the directrory to start with.
 
1744
           returns a generator which yields items in the form:
 
1745
                ((curren_directory_path, fileid),
 
1746
                 [(file1_path, file1_name, file1_kind, None, file1_id,
 
1747
                   file1_kind), ... ])
1732
1748
        """
1733
1749
        raise NotImplementedError(self._walkdirs)
1734
1750
 
1740
1756
        are considered 'resolved', because bzr always puts conflict markers
1741
1757
        into files that have text conflicts.  The corresponding .THIS .BASE and
1742
1758
        .OTHER files are deleted, as per 'resolve'.
1743
 
 
1744
1759
        :return: a tuple of ConflictLists: (un_resolved, resolved).
1745
1760
        """
1746
1761
        un_resolved = _mod_conflicts.ConflictList()
1765
1780
        self.set_conflicts(un_resolved)
1766
1781
        return un_resolved, resolved
1767
1782
 
 
1783
    @needs_read_lock
 
1784
    def _check(self, references):
 
1785
        """Check the tree for consistency.
 
1786
 
 
1787
        :param references: A dict with keys matching the items returned by
 
1788
            self._get_check_refs(), and values from looking those keys up in
 
1789
            the repository.
 
1790
        """
 
1791
        tree_basis = self.basis_tree()
 
1792
        tree_basis.lock_read()
 
1793
        try:
 
1794
            repo_basis = references[('trees', self.last_revision())]
 
1795
            if len(list(repo_basis.iter_changes(tree_basis))) > 0:
 
1796
                raise errors.BzrCheckError(
 
1797
                    "Mismatched basis inventory content.")
 
1798
            self._validate()
 
1799
        finally:
 
1800
            tree_basis.unlock()
 
1801
 
1768
1802
    def _validate(self):
1769
1803
        """Validate internal structures.
1770
1804
 
1776
1810
        """
1777
1811
        return
1778
1812
 
 
1813
    @needs_read_lock
1779
1814
    def check_state(self):
1780
1815
        """Check that the working state is/isn't valid."""
1781
 
        raise NotImplementedError(self.check_state)
 
1816
        check_refs = self._get_check_refs()
 
1817
        refs = {}
 
1818
        for ref in check_refs:
 
1819
            kind, value = ref
 
1820
            if kind == 'trees':
 
1821
                refs[ref] = self.branch.repository.revision_tree(value)
 
1822
        self._check(refs)
1782
1823
 
1783
1824
    def reset_state(self, revision_ids=None):
1784
1825
        """Reset the state of the working tree.
2073
2114
            return True
2074
2115
        return self.inventory.has_id(file_id)
2075
2116
 
 
2117
    __contains__ = has_id
 
2118
 
2076
2119
    @symbol_versioning.deprecated_method(symbol_versioning.deprecated_in((2, 4, 0)))
2077
2120
    def __iter__(self):
2078
2121
        """Iterate through file_ids for this tree.
2091
2134
        if self._change_last_revision(new_revision):
2092
2135
            self._cache_basis_inventory(new_revision)
2093
2136
 
2094
 
    def _get_check_refs(self):
2095
 
        """Return the references needed to perform a check of this tree.
2096
 
        
2097
 
        The default implementation returns no refs, and is only suitable for
2098
 
        trees that have no local caching and can commit on ghosts at any time.
2099
 
 
2100
 
        :seealso: bzrlib.check for details about check_refs.
2101
 
        """
2102
 
        return []
2103
 
 
2104
 
    @needs_read_lock
2105
 
    def _check(self, references):
2106
 
        """Check the tree for consistency.
2107
 
 
2108
 
        :param references: A dict with keys matching the items returned by
2109
 
            self._get_check_refs(), and values from looking those keys up in
2110
 
            the repository.
2111
 
        """
2112
 
        tree_basis = self.basis_tree()
2113
 
        tree_basis.lock_read()
2114
 
        try:
2115
 
            repo_basis = references[('trees', self.last_revision())]
2116
 
            if len(list(repo_basis.iter_changes(tree_basis))) > 0:
2117
 
                raise errors.BzrCheckError(
2118
 
                    "Mismatched basis inventory content.")
2119
 
            self._validate()
2120
 
        finally:
2121
 
            tree_basis.unlock()
2122
 
 
2123
 
    @needs_read_lock
2124
 
    def check_state(self):
2125
 
        """Check that the working state is/isn't valid."""
2126
 
        check_refs = self._get_check_refs()
2127
 
        refs = {}
2128
 
        for ref in check_refs:
2129
 
            kind, value = ref
2130
 
            if kind == 'trees':
2131
 
                refs[ref] = self.branch.repository.revision_tree(value)
2132
 
        self._check(refs)
2133
 
 
2134
2137
    @needs_tree_write_lock
2135
2138
    def reset_state(self, revision_ids=None):
2136
2139
        """Reset the state of the working tree.
2254
2257
                parent_tree = self.branch.repository.revision_tree(parent_id)
2255
2258
            parent_tree.lock_read()
2256
2259
            try:
2257
 
                if not parent_tree.has_id(file_id):
 
2260
                if file_id not in parent_tree:
2258
2261
                    continue
2259
2262
                ie = parent_tree.inventory[file_id]
2260
2263
                if ie.kind != 'file':
2308
2311
            for s in _mod_rio.RioReader(hashfile):
2309
2312
                # RioReader reads in Unicode, so convert file_ids back to utf8
2310
2313
                file_id = osutils.safe_file_id(s.get("file_id"), warn=False)
2311
 
                if not self.inventory.has_id(file_id):
 
2314
                if file_id not in self.inventory:
2312
2315
                    continue
2313
2316
                text_hash = s.get("hash")
2314
2317
                if text_hash == self.get_file_sha1(file_id):
2555
2558
        inventory. The second mode only updates the inventory without
2556
2559
        touching the file on the filesystem.
2557
2560
 
2558
 
        move uses the second mode if 'after == True' and the target is
2559
 
        either not versioned or newly added, and present in the working tree.
 
2561
        move uses the second mode if 'after == True' and the target is not
 
2562
        versioned but present in the working tree.
2560
2563
 
2561
2564
        move uses the second mode if 'after == False' and the source is
2562
2565
        versioned but no longer in the working tree, and the target is not
2709
2712
 
2710
2713
    class _RenameEntry(object):
2711
2714
        def __init__(self, from_rel, from_id, from_tail, from_parent_id,
2712
 
                     to_rel, to_tail, to_parent_id, only_change_inv=False,
2713
 
                     change_id=False):
 
2715
                     to_rel, to_tail, to_parent_id, only_change_inv=False):
2714
2716
            self.from_rel = from_rel
2715
2717
            self.from_id = from_id
2716
2718
            self.from_tail = from_tail
2718
2720
            self.to_rel = to_rel
2719
2721
            self.to_tail = to_tail
2720
2722
            self.to_parent_id = to_parent_id
2721
 
            self.change_id = change_id
2722
2723
            self.only_change_inv = only_change_inv
2723
2724
 
2724
2725
    def _determine_mv_mode(self, rename_entries, after=False):
2736
2737
            to_rel = rename_entry.to_rel
2737
2738
            to_id = inv.path2id(to_rel)
2738
2739
            only_change_inv = False
2739
 
            change_id = False
2740
2740
 
2741
2741
            # check the inventory for source and destination
2742
2742
            if from_id is None:
2743
2743
                raise errors.BzrMoveFailedError(from_rel,to_rel,
2744
2744
                    errors.NotVersionedError(path=from_rel))
2745
2745
            if to_id is not None:
2746
 
                allowed = False
2747
 
                # allow it with --after but only if dest is newly added
2748
 
                if after:
2749
 
                    basis = self.basis_tree()
2750
 
                    basis.lock_read()
2751
 
                    try:
2752
 
                        if not basis.has_id(to_id):
2753
 
                            rename_entry.change_id = True
2754
 
                            allowed = True
2755
 
                    finally:
2756
 
                        basis.unlock()
2757
 
                if not allowed:
2758
 
                    raise errors.BzrMoveFailedError(from_rel,to_rel,
2759
 
                        errors.AlreadyVersionedError(path=to_rel))
 
2746
                raise errors.BzrMoveFailedError(from_rel,to_rel,
 
2747
                    errors.AlreadyVersionedError(path=to_rel))
2760
2748
 
2761
2749
            # try to determine the mode for rename (only change inv or change
2762
2750
            # inv and file system)
2833
2821
            except OSError, e:
2834
2822
                raise errors.BzrMoveFailedError(entry.from_rel,
2835
2823
                    entry.to_rel, e[1])
2836
 
        if entry.change_id:
2837
 
            to_id = inv.path2id(entry.to_rel)
2838
 
            inv.remove_recursive_id(to_id)
2839
2824
        inv.rename(entry.from_id, entry.to_parent_id, entry.to_tail)
2840
2825
 
2841
2826
    @needs_tree_write_lock
2849
2834
        :raises: NoSuchId if any fileid is not currently versioned.
2850
2835
        """
2851
2836
        for file_id in file_ids:
2852
 
            if not self._inventory.has_id(file_id):
 
2837
            if file_id not in self._inventory:
2853
2838
                raise errors.NoSuchId(self, file_id)
2854
2839
        for file_id in file_ids:
2855
2840
            if self._inventory.has_id(file_id):
2914
2899
    def _walkdirs(self, prefix=""):
2915
2900
        """Walk the directories of this tree.
2916
2901
 
2917
 
        :param prefix: is used as the directrory to start with.
2918
 
        :returns: a generator which yields items in the form::
2919
 
 
2920
 
            ((curren_directory_path, fileid),
2921
 
             [(file1_path, file1_name, file1_kind, None, file1_id,
2922
 
               file1_kind), ... ])
 
2902
           :prefix: is used as the directrory to start with.
 
2903
           returns a generator which yields items in the form:
 
2904
                ((curren_directory_path, fileid),
 
2905
                 [(file1_path, file1_name, file1_kind, None, file1_id,
 
2906
                   file1_kind), ... ])
2923
2907
        """
2924
2908
        _directory = 'directory'
2925
2909
        # get the root in the inventory
3010
2994
    missing_parent_conflicts = False
3011
2995
    """If this format supports missing parent conflicts."""
3012
2996
 
3013
 
    supports_versioned_directories = None
3014
 
 
3015
2997
    @classmethod
3016
2998
    def find_format_string(klass, a_bzrdir):
3017
2999
        """Return format name for the working tree object in a_bzrdir."""