~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transform.py

  • Committer: Jelmer Vernooij
  • Date: 2011-11-27 17:42:25 UTC
  • mto: This revision was merged to the branch mainline in revision 6311.
  • Revision ID: jelmer@samba.org-20111127174225-tspfeewl0gwxxumt
Add possible_transports in a couple more places.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
 
from __future__ import absolute_import
18
 
 
19
17
import os
20
18
import errno
21
19
from stat import S_ISREG, S_IEXEC
22
20
import time
23
21
 
24
22
from bzrlib import (
25
 
    config as _mod_config,
26
23
    errors,
27
24
    lazy_import,
28
25
    registry,
48
45
""")
49
46
from bzrlib.errors import (DuplicateKey, MalformedTransform,
50
47
                           ReusingTransform, CantMoveRoot,
51
 
                           ImmortalLimbo, NoFinalPath,
 
48
                           ExistingLimbo, ImmortalLimbo, NoFinalPath,
52
49
                           UnableCreateSymlink)
53
50
from bzrlib.filters import filtered_output_bytes, ContentFilterContext
54
 
from bzrlib.mutabletree import MutableTree
55
51
from bzrlib.osutils import (
56
52
    delete_any,
57
53
    file_kind,
59
55
    pathjoin,
60
56
    sha_file,
61
57
    splitpath,
 
58
    supports_executable,
62
59
    )
63
60
from bzrlib.progress import ProgressPhase
64
61
from bzrlib.symbol_versioning import (
157
154
        """
158
155
        if self._tree is None:
159
156
            return
160
 
        for hook in MutableTree.hooks['post_transform']:
161
 
            hook(self._tree, self)
162
157
        self._tree.unlock()
163
158
        self._tree = None
164
159
 
233
228
        irrelevant.
234
229
 
235
230
        """
236
 
        new_roots = [k for k, v in self._new_parent.iteritems() if v ==
 
231
        new_roots = [k for k, v in self._new_parent.iteritems() if v is
237
232
                     ROOT_PARENT]
238
233
        if len(new_roots) < 1:
239
234
            return
629
624
        for trans_id in self._new_parent:
630
625
            seen = set()
631
626
            parent_id = trans_id
632
 
            while parent_id != ROOT_PARENT:
 
627
            while parent_id is not ROOT_PARENT:
633
628
                seen.add(parent_id)
634
629
                try:
635
630
                    parent_id = self.final_parent(parent_id)
645
640
        """If parent directories are versioned, children must be versioned."""
646
641
        conflicts = []
647
642
        for parent_id, children in by_parent.iteritems():
648
 
            if parent_id == ROOT_PARENT:
 
643
            if parent_id is ROOT_PARENT:
649
644
                continue
650
645
            if self.final_file_id(parent_id) is not None:
651
646
                continue
744
739
        """Children must have a directory parent"""
745
740
        conflicts = []
746
741
        for parent_id, children in by_parent.iteritems():
747
 
            if parent_id == ROOT_PARENT:
 
742
            if parent_id is ROOT_PARENT:
748
743
                continue
749
744
            no_children = True
750
745
            for child_id in children:
766
761
 
767
762
    def _set_executability(self, path, trans_id):
768
763
        """Set the executability of versioned files """
769
 
        if self._tree._supports_executable():
 
764
        if supports_executable():
770
765
            new_executability = self._new_executability[trans_id]
771
766
            abspath = self._tree.abspath(path)
772
767
            current_mode = os.stat(abspath).st_mode
781
776
                    to_mode |= 0010 & ~umask
782
777
            else:
783
778
                to_mode = current_mode & ~0111
784
 
            osutils.chmod_if_possible(abspath, to_mode)
 
779
            os.chmod(abspath, to_mode)
785
780
 
786
781
    def _new_entry(self, name, parent_id, file_id):
787
782
        """Helper function to create a new filesystem entry."""
1236
1231
        finally:
1237
1232
            TreeTransformBase.finalize(self)
1238
1233
 
1239
 
    def _limbo_supports_executable(self):
1240
 
        """Check if the limbo path supports the executable bit."""
1241
 
        # FIXME: Check actual file system capabilities of limbodir
1242
 
        return osutils.supports_executable()
1243
 
 
1244
1234
    def _limbo_name(self, trans_id):
1245
1235
        """Generate the limbo name of a file"""
1246
1236
        limbo_name = self._limbo_files.get(trans_id)
1406
1396
        delete_any(self._limbo_name(trans_id))
1407
1397
 
1408
1398
    def new_orphan(self, trans_id, parent_id):
1409
 
        conf = self._tree.get_config_stack()
1410
 
        handle_orphan = conf.get('bzr.transform.orphan_policy')
 
1399
        # FIXME: There is no tree config, so we use the branch one (it's weird
 
1400
        # to define it this way as orphaning can only occur in a working tree,
 
1401
        # but that's all we have (for now). It will find the option in
 
1402
        # locations.conf or bazaar.conf though) -- vila 20100916
 
1403
        conf = self._tree.branch.get_config()
 
1404
        conf_var_name = 'bzr.transform.orphan_policy'
 
1405
        orphan_policy = conf.get_user_option(conf_var_name)
 
1406
        default_policy = orphaning_registry.default_key
 
1407
        if orphan_policy is None:
 
1408
            orphan_policy = default_policy
 
1409
        if orphan_policy not in orphaning_registry:
 
1410
            trace.warning('%s (from %s) is not a known policy, defaulting '
 
1411
                'to %s' % (orphan_policy, conf_var_name, default_policy))
 
1412
            orphan_policy = default_policy
 
1413
        handle_orphan = orphaning_registry.get(orphan_policy)
1411
1414
        handle_orphan(self, trans_id, parent_id)
1412
1415
 
1413
1416
 
1476
1479
orphaning_registry._set_default_key('conflict')
1477
1480
 
1478
1481
 
1479
 
opt_transform_orphan = _mod_config.RegistryOption(
1480
 
    'bzr.transform.orphan_policy', orphaning_registry,
1481
 
    help='Policy for orphaned files during transform operations.',
1482
 
    invalid='warning')
1483
 
 
1484
 
 
1485
1482
class TreeTransform(DiskTreeTransform):
1486
1483
    """Represent a tree transformation.
1487
1484
 
1558
1555
        try:
1559
1556
            limbodir = urlutils.local_path_from_url(
1560
1557
                tree._transport.abspath('limbo'))
1561
 
            osutils.ensure_empty_directory_exists(
1562
 
                limbodir,
1563
 
                errors.ExistingLimbo)
 
1558
            try:
 
1559
                os.mkdir(limbodir)
 
1560
            except OSError, e:
 
1561
                if e.errno == errno.EEXIST:
 
1562
                    raise ExistingLimbo(limbodir)
1564
1563
            deletiondir = urlutils.local_path_from_url(
1565
1564
                tree._transport.abspath('pending-deletion'))
1566
 
            osutils.ensure_empty_directory_exists(
1567
 
                deletiondir,
1568
 
                errors.ExistingPendingDeletion)
 
1565
            try:
 
1566
                os.mkdir(deletiondir)
 
1567
            except OSError, e:
 
1568
                if e.errno == errno.EEXIST:
 
1569
                    raise errors.ExistingPendingDeletion(deletiondir)
1569
1570
        except:
1570
1571
            tree.unlock()
1571
1572
            raise
1634
1635
            else:
1635
1636
                raise
1636
1637
        if typefunc(mode):
1637
 
            osutils.chmod_if_possible(self._limbo_name(trans_id), mode)
 
1638
            os.chmod(self._limbo_name(trans_id), mode)
1638
1639
 
1639
1640
    def iter_tree_children(self, parent_id):
1640
1641
        """Iterate through the entry's tree children, if any"""
1718
1719
            calculating one.
1719
1720
        :param _mover: Supply an alternate FileMover, for testing
1720
1721
        """
1721
 
        for hook in MutableTree.hooks['pre_transform']:
1722
 
            hook(self._tree, self)
1723
1722
        if not no_conflicts:
1724
1723
            self._check_malformed()
1725
1724
        child_pb = ui.ui_factory.nested_progress_bar()
2056
2055
        pass
2057
2056
 
2058
2057
    @property
2059
 
    @deprecated_method(deprecated_in((2, 5, 0)))
2060
2058
    def inventory(self):
2061
2059
        """This Tree does not use inventory as its backing data."""
2062
2060
        raise NotImplementedError(_PreviewTree.inventory)
2063
2061
 
2064
 
    @property
2065
 
    def root_inventory(self):
2066
 
        """This Tree does not use inventory as its backing data."""
2067
 
        raise NotImplementedError(_PreviewTree.root_inventory)
2068
 
 
2069
2062
    def get_root_id(self):
2070
2063
        return self._transform.final_file_id(self._transform.root)
2071
2064
 
2330
2323
            if kind == 'file':
2331
2324
                statval = os.lstat(limbo_name)
2332
2325
                size = statval.st_size
2333
 
                if not tt._limbo_supports_executable():
 
2326
                if not supports_executable():
2334
2327
                    executable = False
2335
2328
                else:
2336
2329
                    executable = statval.st_mode & S_IEXEC