~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transform.py

(jelmer) Use the absolute_import feature everywhere in bzrlib,
 and add a source test to make sure it's used everywhere. (Jelmer Vernooij)

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
import time
23
23
 
24
24
from bzrlib import (
25
 
    config as _mod_config,
26
25
    errors,
27
26
    lazy_import,
28
27
    registry,
48
47
""")
49
48
from bzrlib.errors import (DuplicateKey, MalformedTransform,
50
49
                           ReusingTransform, CantMoveRoot,
51
 
                           ImmortalLimbo, NoFinalPath,
 
50
                           ExistingLimbo, ImmortalLimbo, NoFinalPath,
52
51
                           UnableCreateSymlink)
53
52
from bzrlib.filters import filtered_output_bytes, ContentFilterContext
54
 
from bzrlib.mutabletree import MutableTree
55
53
from bzrlib.osutils import (
56
54
    delete_any,
57
55
    file_kind,
59
57
    pathjoin,
60
58
    sha_file,
61
59
    splitpath,
 
60
    supports_executable,
62
61
    )
63
62
from bzrlib.progress import ProgressPhase
64
63
from bzrlib.symbol_versioning import (
157
156
        """
158
157
        if self._tree is None:
159
158
            return
160
 
        for hook in MutableTree.hooks['post_transform']:
161
 
            hook(self._tree, self)
162
159
        self._tree.unlock()
163
160
        self._tree = None
164
161
 
233
230
        irrelevant.
234
231
 
235
232
        """
236
 
        new_roots = [k for k, v in self._new_parent.iteritems() if v ==
 
233
        new_roots = [k for k, v in self._new_parent.iteritems() if v is
237
234
                     ROOT_PARENT]
238
235
        if len(new_roots) < 1:
239
236
            return
575
572
            # ensure that all children are registered with the transaction
576
573
            list(self.iter_tree_children(parent_id))
577
574
 
 
575
    @deprecated_method(deprecated_in((2, 3, 0)))
 
576
    def has_named_child(self, by_parent, parent_id, name):
 
577
        return self._has_named_child(
 
578
            name, parent_id, known_children=by_parent.get(parent_id, []))
 
579
 
578
580
    def _has_named_child(self, name, parent_id, known_children):
579
581
        """Does a parent already have a name child.
580
582
 
624
626
        for trans_id in self._new_parent:
625
627
            seen = set()
626
628
            parent_id = trans_id
627
 
            while parent_id != ROOT_PARENT:
 
629
            while parent_id is not ROOT_PARENT:
628
630
                seen.add(parent_id)
629
631
                try:
630
632
                    parent_id = self.final_parent(parent_id)
640
642
        """If parent directories are versioned, children must be versioned."""
641
643
        conflicts = []
642
644
        for parent_id, children in by_parent.iteritems():
643
 
            if parent_id == ROOT_PARENT:
 
645
            if parent_id is ROOT_PARENT:
644
646
                continue
645
647
            if self.final_file_id(parent_id) is not None:
646
648
                continue
739
741
        """Children must have a directory parent"""
740
742
        conflicts = []
741
743
        for parent_id, children in by_parent.iteritems():
742
 
            if parent_id == ROOT_PARENT:
 
744
            if parent_id is ROOT_PARENT:
743
745
                continue
744
746
            no_children = True
745
747
            for child_id in children:
761
763
 
762
764
    def _set_executability(self, path, trans_id):
763
765
        """Set the executability of versioned files """
764
 
        if self._tree._supports_executable():
 
766
        if supports_executable():
765
767
            new_executability = self._new_executability[trans_id]
766
768
            abspath = self._tree.abspath(path)
767
769
            current_mode = os.stat(abspath).st_mode
1231
1233
        finally:
1232
1234
            TreeTransformBase.finalize(self)
1233
1235
 
1234
 
    def _limbo_supports_executable(self):
1235
 
        """Check if the limbo path supports the executable bit."""
1236
 
        # FIXME: Check actual file system capabilities of limbodir
1237
 
        return osutils.supports_executable()
1238
 
 
1239
1236
    def _limbo_name(self, trans_id):
1240
1237
        """Generate the limbo name of a file"""
1241
1238
        limbo_name = self._limbo_files.get(trans_id)
1401
1398
        delete_any(self._limbo_name(trans_id))
1402
1399
 
1403
1400
    def new_orphan(self, trans_id, parent_id):
1404
 
        conf = self._tree.get_config_stack()
1405
 
        handle_orphan = conf.get('bzr.transform.orphan_policy')
 
1401
        # FIXME: There is no tree config, so we use the branch one (it's weird
 
1402
        # to define it this way as orphaning can only occur in a working tree,
 
1403
        # but that's all we have (for now). It will find the option in
 
1404
        # locations.conf or bazaar.conf though) -- vila 20100916
 
1405
        conf = self._tree.branch.get_config()
 
1406
        conf_var_name = 'bzr.transform.orphan_policy'
 
1407
        orphan_policy = conf.get_user_option(conf_var_name)
 
1408
        default_policy = orphaning_registry.default_key
 
1409
        if orphan_policy is None:
 
1410
            orphan_policy = default_policy
 
1411
        if orphan_policy not in orphaning_registry:
 
1412
            trace.warning('%s (from %s) is not a known policy, defaulting '
 
1413
                'to %s' % (orphan_policy, conf_var_name, default_policy))
 
1414
            orphan_policy = default_policy
 
1415
        handle_orphan = orphaning_registry.get(orphan_policy)
1406
1416
        handle_orphan(self, trans_id, parent_id)
1407
1417
 
1408
1418
 
1471
1481
orphaning_registry._set_default_key('conflict')
1472
1482
 
1473
1483
 
1474
 
opt_transform_orphan = _mod_config.RegistryOption(
1475
 
    'bzr.transform.orphan_policy', orphaning_registry,
1476
 
    help='Policy for orphaned files during transform operations.',
1477
 
    invalid='warning')
1478
 
 
1479
 
 
1480
1484
class TreeTransform(DiskTreeTransform):
1481
1485
    """Represent a tree transformation.
1482
1486
 
1713
1717
            calculating one.
1714
1718
        :param _mover: Supply an alternate FileMover, for testing
1715
1719
        """
1716
 
        for hook in MutableTree.hooks['pre_transform']:
1717
 
            hook(self._tree, self)
1718
1720
        if not no_conflicts:
1719
1721
            self._check_malformed()
1720
1722
        child_pb = ui.ui_factory.nested_progress_bar()
2051
2053
        pass
2052
2054
 
2053
2055
    @property
2054
 
    @deprecated_method(deprecated_in((2, 5, 0)))
2055
2056
    def inventory(self):
2056
2057
        """This Tree does not use inventory as its backing data."""
2057
2058
        raise NotImplementedError(_PreviewTree.inventory)
2058
2059
 
2059
 
    @property
2060
 
    def root_inventory(self):
2061
 
        """This Tree does not use inventory as its backing data."""
2062
 
        raise NotImplementedError(_PreviewTree.root_inventory)
2063
 
 
2064
2060
    def get_root_id(self):
2065
2061
        return self._transform.final_file_id(self._transform.root)
2066
2062
 
2112
2108
        return cur_parent
2113
2109
 
2114
2110
    def path2id(self, path):
2115
 
        if isinstance(path, list):
2116
 
            if path == []:
2117
 
                path = [""]
2118
 
            path = osutils.pathjoin(*path)
2119
2111
        return self._transform.final_file_id(self._path2trans_id(path))
2120
2112
 
2121
2113
    def id2path(self, file_id):
2182
2174
                ordered_ids.append((trans_id, parent_file_id))
2183
2175
        return ordered_ids
2184
2176
 
2185
 
    def iter_child_entries(self, file_id, path=None):
2186
 
        self.id2path(file_id)
2187
 
        trans_id = self._transform.trans_id_file_id(file_id)
2188
 
        todo = [(child_trans_id, trans_id) for child_trans_id in
2189
 
                self._all_children(trans_id)]
2190
 
        for entry, trans_id in self._make_inv_entries(todo):
2191
 
            yield entry
2192
 
 
2193
2177
    def iter_entries_by_dir(self, specific_file_ids=None, yield_parents=False):
2194
2178
        # This may not be a maximally efficient implementation, but it is
2195
2179
        # reasonably straightforward.  An implementation that grafts the
2337
2321
            if kind == 'file':
2338
2322
                statval = os.lstat(limbo_name)
2339
2323
                size = statval.st_size
2340
 
                if not tt._limbo_supports_executable():
 
2324
                if not supports_executable():
2341
2325
                    executable = False
2342
2326
                else:
2343
2327
                    executable = statval.st_mode & S_IEXEC
2832
2816
        tt.set_executability(entry.executable, trans_id)
2833
2817
 
2834
2818
 
 
2819
@deprecated_function(deprecated_in((2, 3, 0)))
 
2820
def get_backup_name(entry, by_parent, parent_trans_id, tt):
 
2821
    return _get_backup_name(entry.name, by_parent, parent_trans_id, tt)
 
2822
 
 
2823
 
 
2824
@deprecated_function(deprecated_in((2, 3, 0)))
 
2825
def _get_backup_name(name, by_parent, parent_trans_id, tt):
 
2826
    """Produce a backup-style name that appears to be available"""
 
2827
    def name_gen():
 
2828
        counter = 1
 
2829
        while True:
 
2830
            yield "%s.~%d~" % (name, counter)
 
2831
            counter += 1
 
2832
    for new_name in name_gen():
 
2833
        if not tt.has_named_child(by_parent, parent_trans_id, new_name):
 
2834
            return new_name
 
2835
 
 
2836
 
2835
2837
def revert(working_tree, target_tree, filenames, backups=False,
2836
2838
           pb=None, change_reporter=None):
2837
2839
    """Revert a working tree's contents to those of a target tree."""