~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: Jelmer Vernooij
  • Date: 2012-01-23 19:08:05 UTC
  • mfrom: (6437.3.20 2.5)
  • mto: This revision was merged to the branch mainline in revision 6450.
  • Revision ID: jelmer@samba.org-20120123190805-hlcuihkt2dep44cw
merge bzr 2.5.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
WorkingTree.open(dir).
30
30
"""
31
31
 
 
32
from __future__ import absolute_import
32
33
 
33
34
from cStringIO import StringIO
34
35
import os
46
47
 
47
48
from bzrlib import (
48
49
    branch,
49
 
    bzrdir,
50
50
    conflicts as _mod_conflicts,
51
51
    controldir,
52
52
    errors,
69
69
    )
70
70
""")
71
71
 
72
 
from bzrlib import symbol_versioning
 
72
# Explicitly import bzrlib.bzrdir so that the BzrProber
 
73
# is guaranteed to be registered.
 
74
from bzrlib import (
 
75
    bzrdir,
 
76
    symbol_versioning,
 
77
    )
 
78
 
73
79
from bzrlib.decorators import needs_read_lock, needs_write_lock
74
80
from bzrlib.i18n import gettext
75
81
from bzrlib.lock import LogicalLockResult
84
90
    realpath,
85
91
    safe_unicode,
86
92
    splitpath,
87
 
    supports_executable,
88
93
    )
89
94
from bzrlib.trace import mutter, note
90
95
from bzrlib.revision import CURRENT_REVISION
228
233
        """See `Tree.has_versioned_directories`."""
229
234
        return self._format.supports_versioned_directories
230
235
 
 
236
    def _supports_executable(self):
 
237
        if sys.platform == 'win32':
 
238
            return False
 
239
        # FIXME: Ideally this should check the file system
 
240
        return True
 
241
 
231
242
    def break_lock(self):
232
243
        """Break a lock if one is present from another instance.
233
244
 
257
268
        """
258
269
        if path is None:
259
270
            path = osutils.getcwd()
260
 
        control = controldir.ControlDir.open(path, _unsupported)
261
 
        return control.open_workingtree(_unsupported)
 
271
        control = controldir.ControlDir.open(path, _unsupported=_unsupported)
 
272
        return control.open_workingtree(unsupported=_unsupported)
262
273
 
263
274
    @staticmethod
264
275
    def open_containing(path=None):
1112
1123
        else:
1113
1124
            mode = stat_value.st_mode
1114
1125
            kind = osutils.file_kind_from_stat_mode(mode)
1115
 
            if not supports_executable():
 
1126
            if not self._supports_executable():
1116
1127
                executable = entry is not None and entry.executable
1117
1128
            else:
1118
1129
                executable = bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
2187
2198
        mode = stat_result.st_mode
2188
2199
        return bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
2189
2200
 
2190
 
    if not supports_executable():
2191
 
        def is_executable(self, file_id, path=None):
 
2201
    def is_executable(self, file_id, path=None):
 
2202
        if not self._supports_executable():
2192
2203
            return self._inventory[file_id].executable
2193
 
 
2194
 
        _is_executable_from_path_and_stat = \
2195
 
            _is_executable_from_path_and_stat_from_basis
2196
 
    else:
2197
 
        def is_executable(self, file_id, path=None):
 
2204
        else:
2198
2205
            if not path:
2199
2206
                path = self.id2path(file_id)
2200
2207
            mode = os.lstat(self.abspath(path)).st_mode
2201
2208
            return bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
2202
2209
 
2203
 
        _is_executable_from_path_and_stat = \
2204
 
            _is_executable_from_path_and_stat_from_stat
 
2210
    def _is_executable_from_path_and_stat(self, path, stat_result):
 
2211
        if not self._supports_executable():
 
2212
            return self._is_executable_from_path_and_stat_from_basis(path, stat_result)
 
2213
        else:
 
2214
            return self._is_executable_from_path_and_stat_from_stat(path, stat_result)
2205
2215
 
2206
2216
    @needs_tree_write_lock
2207
2217
    def _add(self, files, ids, kinds):
2410
2420
        tree_transport = self.bzrdir.root_transport.clone(sub_path)
2411
2421
        if tree_transport.base != branch_transport.base:
2412
2422
            tree_bzrdir = format.initialize_on_transport(tree_transport)
2413
 
            branch.BranchReferenceFormat().initialize(tree_bzrdir,
2414
 
                target_branch=new_branch)
 
2423
            tree_bzrdir.set_branch_reference(new_branch)
2415
2424
        else:
2416
2425
            tree_bzrdir = branch_bzrdir
2417
2426
        wt = tree_bzrdir.create_workingtree(_mod_revision.NULL_REVISION)
2795
2804
                # something is wrong, so lets determine what exactly
2796
2805
                if not self.has_filename(from_rel) and \
2797
2806
                   not self.has_filename(to_rel):
2798
 
                    raise errors.BzrRenameFailedError(from_rel,to_rel,
2799
 
                        errors.PathsDoNotExist(paths=(str(from_rel),
2800
 
                        str(to_rel))))
 
2807
                    raise errors.BzrRenameFailedError(from_rel, to_rel,
 
2808
                        errors.PathsDoNotExist(paths=(from_rel, to_rel)))
2801
2809
                else:
2802
2810
                    raise errors.RenameFailedFilesExist(from_rel, to_rel)
2803
2811
            rename_entry.only_change_inv = only_change_inv
2968
2976
                if dir[2] == _directory:
2969
2977
                    pending.append(dir)
2970
2978
 
 
2979
    @needs_write_lock
 
2980
    def update_feature_flags(self, updated_flags):
 
2981
        """Update the feature flags for this branch.
 
2982
 
 
2983
        :param updated_flags: Dictionary mapping feature names to necessities
 
2984
            A necessity can be None to indicate the feature should be removed
 
2985
        """
 
2986
        self._format._update_feature_flags(updated_flags)
 
2987
        self.control_transport.put_bytes('format', self._format.as_string())
 
2988
 
2971
2989
 
2972
2990
class WorkingTreeFormatRegistry(controldir.ControlComponentFormatRegistry):
2973
2991
    """Registry for working tree formats."""
3029
3047
 
3030
3048
    supports_versioned_directories = None
3031
3049
 
3032
 
    @classmethod
3033
 
    def find_format_string(klass, controldir):
3034
 
        """Return format name for the working tree object in controldir."""
3035
 
        try:
3036
 
            transport = controldir.get_workingtree_transport(None)
3037
 
            return transport.get_bytes("format")
3038
 
        except errors.NoSuchFile:
3039
 
            raise errors.NoWorkingTree(base=transport.base)
3040
 
 
3041
 
    @classmethod
3042
 
    def find_format(klass, controldir):
3043
 
        """Return the format for the working tree object in controldir."""
3044
 
        try:
3045
 
            format_string = klass.find_format_string(controldir)
3046
 
            return format_registry.get(format_string)
3047
 
        except KeyError:
3048
 
            raise errors.UnknownFormatError(format=format_string,
3049
 
                                            kind="working tree")
3050
 
 
3051
3050
    def initialize(self, controldir, revision_id=None, from_branch=None,
3052
3051
                   accelerator_tree=None, hardlink=False):
3053
3052
        """Initialize a new working tree in controldir.
3078
3077
        """Return the current default format."""
3079
3078
        return format_registry.get_default()
3080
3079
 
3081
 
    def get_format_string(self):
3082
 
        """Return the ASCII format string that identifies this format."""
3083
 
        raise NotImplementedError(self.get_format_string)
3084
 
 
3085
3080
    def get_format_description(self):
3086
3081
        """Return the short description for this format."""
3087
3082
        raise NotImplementedError(self.get_format_description)
3148
3143
        return self._matchingbzrdir
3149
3144
 
3150
3145
 
 
3146
class WorkingTreeFormatMetaDir(bzrdir.BzrFormat, WorkingTreeFormat):
 
3147
    """Base class for working trees that live in bzr meta directories."""
 
3148
 
 
3149
    def __init__(self):
 
3150
        WorkingTreeFormat.__init__(self)
 
3151
        bzrdir.BzrFormat.__init__(self)
 
3152
 
 
3153
    @classmethod
 
3154
    def find_format_string(klass, controldir):
 
3155
        """Return format name for the working tree object in controldir."""
 
3156
        try:
 
3157
            transport = controldir.get_workingtree_transport(None)
 
3158
            return transport.get_bytes("format")
 
3159
        except errors.NoSuchFile:
 
3160
            raise errors.NoWorkingTree(base=transport.base)
 
3161
 
 
3162
    @classmethod
 
3163
    def find_format(klass, controldir):
 
3164
        """Return the format for the working tree object in controldir."""
 
3165
        format_string = klass.find_format_string(controldir)
 
3166
        return klass._find_format(format_registry, 'working tree',
 
3167
                format_string)
 
3168
 
 
3169
    def check_support_status(self, allow_unsupported, recommend_upgrade=True,
 
3170
            basedir=None):
 
3171
        WorkingTreeFormat.check_support_status(self,
 
3172
            allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
 
3173
            basedir=basedir)
 
3174
        bzrdir.BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
 
3175
            recommend_upgrade=recommend_upgrade, basedir=basedir)
 
3176
 
 
3177
 
3151
3178
format_registry.register_lazy("Bazaar Working Tree Format 4 (bzr 0.15)\n",
3152
3179
    "bzrlib.workingtree_4", "WorkingTreeFormat4")
3153
3180
format_registry.register_lazy("Bazaar Working Tree Format 5 (bzr 1.11)\n",