~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: John Arbash Meinel
  • Date: 2011-08-30 10:54:28 UTC
  • mfrom: (5609.48.9 2.3)
  • mto: (6015.28.2 2.4)
  • mto: This revision was merged to the branch mainline in revision 6124.
  • Revision ID: john@arbash-meinel.com-20110830105428-3xu4hkvizhfj5k11
Merge 2.3 into 2.4, and fix up the conflict for resolving bug #835035

Show diffs side-by-side

added added

removed removed

Lines of Context:
54
54
    generate_ids,
55
55
    globbing,
56
56
    graph as _mod_graph,
 
57
    hashcache,
57
58
    ignores,
58
59
    inventory,
59
60
    merge,
71
72
 
72
73
from bzrlib import symbol_versioning
73
74
from bzrlib.decorators import needs_read_lock, needs_write_lock
74
 
from bzrlib.i18n import gettext
75
75
from bzrlib.lock import LogicalLockResult
76
76
import bzrlib.mutabletree
77
77
from bzrlib.mutabletree import needs_tree_write_lock
194
194
        self.basedir = realpath(basedir)
195
195
        self._control_files = _control_files
196
196
        self._transport = self._control_files._transport
 
197
        # update the whole cache up front and write to disk if anything changed;
 
198
        # in the future we might want to do this more selectively
 
199
        # two possible ways offer themselves : in self._unlock, write the cache
 
200
        # if needed, or, when the cache sees a change, append it to the hash
 
201
        # cache file, and have the parser take the most recent entry for a
 
202
        # given path only.
 
203
        wt_trans = self.bzrdir.get_workingtree_transport(None)
 
204
        cache_filename = wt_trans.local_abspath('stat-cache')
 
205
        self._hashcache = hashcache.HashCache(basedir, cache_filename,
 
206
            self.bzrdir._get_file_mode(),
 
207
            self._content_filter_stack_provider())
 
208
        hc = self._hashcache
 
209
        hc.read()
 
210
        # is this scan needed ? it makes things kinda slow.
 
211
        #hc.scan()
 
212
 
 
213
        if hc.needs_write:
 
214
            mutter("write hc")
 
215
            hc.write()
 
216
 
 
217
        self._detect_case_handling()
197
218
        self._rules_searcher = None
198
219
        self.views = self._make_views()
199
220
 
217
238
        """
218
239
        return self.bzrdir.is_control_filename(filename)
219
240
 
 
241
    def _detect_case_handling(self):
 
242
        wt_trans = self.bzrdir.get_workingtree_transport(None)
 
243
        try:
 
244
            wt_trans.stat(self._format.case_sensitive_filename)
 
245
        except errors.NoSuchFile:
 
246
            self.case_sensitive = True
 
247
        else:
 
248
            self.case_sensitive = False
 
249
 
 
250
        self._setup_directory_is_tree_reference()
 
251
 
220
252
    branch = property(
221
253
        fget=lambda self: self._branch,
222
254
        doc="""The branch this WorkingTree is connected to.
225
257
            the working tree has been constructed from.
226
258
            """)
227
259
 
228
 
    def has_versioned_directories(self):
229
 
        """See `Tree.has_versioned_directories`."""
230
 
        return self._format.supports_versioned_directories
231
 
 
232
260
    def break_lock(self):
233
261
        """Break a lock if one is present from another instance.
234
262
 
259
287
        """
260
288
        if path is None:
261
289
            path = osutils.getcwd()
262
 
        control = controldir.ControlDir.open(path, _unsupported)
 
290
        control = bzrdir.BzrDir.open(path, _unsupported)
263
291
        return control.open_workingtree(_unsupported)
264
292
 
265
293
    @staticmethod
277
305
        """
278
306
        if path is None:
279
307
            path = osutils.getcwd()
280
 
        control, relpath = controldir.ControlDir.open_containing(path)
 
308
        control, relpath = bzrdir.BzrDir.open_containing(path)
281
309
        return control.open_workingtree(), relpath
282
310
 
283
311
    @staticmethod
303
331
                if view_files:
304
332
                    file_list = view_files
305
333
                    view_str = views.view_display_str(view_files)
306
 
                    note(gettext("Ignoring files outside view. View is %s") % view_str)
 
334
                    note("Ignoring files outside view. View is %s" % view_str)
307
335
            return tree, file_list
308
336
        if default_directory == u'.':
309
337
            seed = file_list[0]
366
394
            else:
367
395
                return True, tree
368
396
        t = transport.get_transport(location)
369
 
        iterator = controldir.ControlDir.find_bzrdirs(t, evaluate=evaluate,
 
397
        iterator = bzrdir.BzrDir.find_bzrdirs(t, evaluate=evaluate,
370
398
                                              list_current=list_current)
371
399
        return [tr for tr in iterator if tr is not None]
372
400
 
494
522
        raise NotImplementedError(self.get_root_id)
495
523
 
496
524
    @needs_read_lock
497
 
    def clone(self, to_controldir, revision_id=None):
 
525
    def clone(self, to_bzrdir, revision_id=None):
498
526
        """Duplicate this working tree into to_bzr, including all state.
499
527
 
500
528
        Specifically modified files are kept as modified, but
501
529
        ignored and unknown files are discarded.
502
530
 
503
 
        If you want to make a new line of development, see ControlDir.sprout()
 
531
        If you want to make a new line of development, see bzrdir.sprout()
504
532
 
505
533
        revision
506
534
            If not None, the cloned tree will have its last revision set to
508
536
            and this one merged in.
509
537
        """
510
538
        # assumes the target bzr dir format is compatible.
511
 
        result = to_controldir.create_workingtree()
 
539
        result = to_bzrdir.create_workingtree()
512
540
        self.copy_content_into(result, revision_id)
513
541
        return result
514
542
 
567
595
            else:
568
596
                return None
569
597
 
 
598
    def get_file_sha1(self, file_id, path=None, stat_value=None):
 
599
        # FIXME: Shouldn't this be in Tree?
 
600
        raise NotImplementedError(self.get_file_sha1)
 
601
 
570
602
    @needs_tree_write_lock
571
603
    def _gather_kinds(self, files, kinds):
572
604
        """See MutableTree._gather_kinds."""
1034
1066
            stream.write(bytes)
1035
1067
        finally:
1036
1068
            stream.close()
 
1069
        # TODO: update the hashcache here ?
1037
1070
 
1038
1071
    def extras(self):
1039
1072
        """Yield all unversioned files in this WorkingTree.
1499
1532
                                             show_base=show_base)
1500
1533
            if nb_conflicts:
1501
1534
                self.add_parent_tree((old_tip, other_tree))
1502
 
                note(gettext('Rerun update after fixing the conflicts.'))
 
1535
                note('Rerun update after fixing the conflicts.')
1503
1536
                return nb_conflicts
1504
1537
 
1505
1538
        if last_rev != _mod_revision.ensure_null(revision):
1547
1580
            last_rev = parent_trees[0][0]
1548
1581
        return nb_conflicts
1549
1582
 
 
1583
    def _write_hashcache_if_dirty(self):
 
1584
        """Write out the hashcache if it is dirty."""
 
1585
        if self._hashcache.needs_write:
 
1586
            try:
 
1587
                self._hashcache.write()
 
1588
            except OSError, e:
 
1589
                if e.errno not in (errno.EPERM, errno.EACCES):
 
1590
                    raise
 
1591
                # TODO: jam 20061219 Should this be a warning? A single line
 
1592
                #       warning might be sufficient to let the user know what
 
1593
                #       is going on.
 
1594
                mutter('Could not write hashcache for %s\nError: %s',
 
1595
                              self._hashcache.cache_file_name(), e)
 
1596
 
1550
1597
    def set_conflicts(self, arg):
1551
1598
        raise errors.UnsupportedOperation(self.set_conflicts, self)
1552
1599
 
1784
1831
            branch=branch, _control_files=_control_files, _internal=_internal,
1785
1832
            _format=_format, _bzrdir=_bzrdir)
1786
1833
 
1787
 
        self._detect_case_handling()
1788
 
 
1789
1834
        if _inventory is None:
1790
1835
            # This will be acquired on lock_read() or lock_write()
1791
1836
            self._inventory_is_modified = False
1810
1855
        self._inventory = inv
1811
1856
        self._inventory_is_modified = dirty
1812
1857
 
1813
 
    def _detect_case_handling(self):
1814
 
        wt_trans = self.bzrdir.get_workingtree_transport(None)
1815
 
        try:
1816
 
            wt_trans.stat(self._format.case_sensitive_filename)
1817
 
        except errors.NoSuchFile:
1818
 
            self.case_sensitive = True
1819
 
        else:
1820
 
            self.case_sensitive = False
1821
 
 
1822
 
        self._setup_directory_is_tree_reference()
1823
 
 
1824
1858
    def _serialize(self, inventory, out_file):
1825
1859
        xml5.serializer_v5.write_inventory(self._inventory, out_file,
1826
1860
            working=True)
2130
2164
            mode=self.bzrdir._get_file_mode())
2131
2165
        self._inventory_is_modified = False
2132
2166
 
 
2167
    @needs_read_lock
 
2168
    def get_file_sha1(self, file_id, path=None, stat_value=None):
 
2169
        if not path:
 
2170
            path = self._inventory.id2path(file_id)
 
2171
        return self._hashcache.get_sha1(path, stat_value)
 
2172
 
2133
2173
    def get_file_mtime(self, file_id, path=None):
2134
2174
        """See Tree.get_file_mtime."""
2135
2175
        if not path:
2136
2176
            path = self.inventory.id2path(file_id)
2137
 
        try:
2138
 
            return os.lstat(self.abspath(path)).st_mtime
2139
 
        except OSError, e:
2140
 
            if e.errno == errno.ENOENT:
2141
 
                raise errors.FileTimestampUnavailable(path)
2142
 
            raise
 
2177
        return os.lstat(self.abspath(path)).st_mtime
2143
2178
 
2144
2179
    def _is_executable_from_path_and_stat_from_basis(self, path, stat_result):
2145
2180
        file_id = self.path2id(path)
2982
3017
    supports_versioned_directories = None
2983
3018
 
2984
3019
    @classmethod
2985
 
    def find_format_string(klass, controldir):
2986
 
        """Return format name for the working tree object in controldir."""
 
3020
    def find_format_string(klass, a_bzrdir):
 
3021
        """Return format name for the working tree object in a_bzrdir."""
2987
3022
        try:
2988
 
            transport = controldir.get_workingtree_transport(None)
 
3023
            transport = a_bzrdir.get_workingtree_transport(None)
2989
3024
            return transport.get_bytes("format")
2990
3025
        except errors.NoSuchFile:
2991
3026
            raise errors.NoWorkingTree(base=transport.base)
2992
3027
 
2993
3028
    @classmethod
2994
 
    def find_format(klass, controldir):
2995
 
        """Return the format for the working tree object in controldir."""
 
3029
    def find_format(klass, a_bzrdir):
 
3030
        """Return the format for the working tree object in a_bzrdir."""
2996
3031
        try:
2997
 
            format_string = klass.find_format_string(controldir)
 
3032
            format_string = klass.find_format_string(a_bzrdir)
2998
3033
            return format_registry.get(format_string)
2999
3034
        except KeyError:
3000
3035
            raise errors.UnknownFormatError(format=format_string,
3001
3036
                                            kind="working tree")
3002
3037
 
3003
 
    def initialize(self, controldir, revision_id=None, from_branch=None,
 
3038
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
3004
3039
                   accelerator_tree=None, hardlink=False):
3005
 
        """Initialize a new working tree in controldir.
 
3040
        """Initialize a new working tree in a_bzrdir.
3006
3041
 
3007
 
        :param controldir: ControlDir to initialize the working tree in.
 
3042
        :param a_bzrdir: BzrDir to initialize the working tree in.
3008
3043
        :param revision_id: allows creating a working tree at a different
3009
3044
            revision than the branch is at.
3010
3045
        :param from_branch: Branch to checkout
3091
3126
    def unregister_format(klass, format):
3092
3127
        format_registry.remove(format)
3093
3128
 
3094
 
    def get_controldir_for_branch(self):
3095
 
        """Get the control directory format for creating branches.
3096
 
 
3097
 
        This is to support testing of working tree formats that can not exist
3098
 
        in the same control directory as a branch.
3099
 
        """
3100
 
        return self._matchingbzrdir
3101
 
 
3102
3129
 
3103
3130
format_registry.register_lazy("Bazaar Working Tree Format 4 (bzr 0.15)\n",
3104
3131
    "bzrlib.workingtree_4", "WorkingTreeFormat4")