~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

(gz) Fix deprecations of win32utils path function unicode wrappers (Martin
 Packman)

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
54
55
    generate_ids,
55
56
    globbing,
56
57
    graph as _mod_graph,
57
 
    hashcache,
58
58
    ignores,
59
59
    inventory,
60
60
    merge,
70
70
    )
71
71
""")
72
72
 
 
73
# Explicitly import bzrlib.bzrdir so that the BzrProber
 
74
# is guaranteed to be registered.
 
75
import bzrlib.bzrdir
 
76
 
73
77
from bzrlib import symbol_versioning
74
78
from bzrlib.decorators import needs_read_lock, needs_write_lock
 
79
from bzrlib.i18n import gettext
75
80
from bzrlib.lock import LogicalLockResult
76
81
import bzrlib.mutabletree
77
82
from bzrlib.mutabletree import needs_tree_write_lock
84
89
    realpath,
85
90
    safe_unicode,
86
91
    splitpath,
87
 
    supports_executable,
88
92
    )
89
93
from bzrlib.trace import mutter, note
90
94
from bzrlib.revision import CURRENT_REVISION
172
176
 
173
177
    def __init__(self, basedir='.',
174
178
                 branch=DEPRECATED_PARAMETER,
175
 
                 _control_files=None,
176
179
                 _internal=False,
 
180
                 _transport=None,
177
181
                 _format=None,
178
182
                 _bzrdir=None):
179
183
        """Construct a WorkingTree instance. This is not a public API.
192
196
        else:
193
197
            self._branch = self.bzrdir.open_branch()
194
198
        self.basedir = realpath(basedir)
195
 
        self._control_files = _control_files
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()
 
199
        self._transport = _transport
218
200
        self._rules_searcher = None
219
201
        self.views = self._make_views()
220
202
 
238
220
        """
239
221
        return self.bzrdir.is_control_filename(filename)
240
222
 
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
 
 
252
223
    branch = property(
253
224
        fget=lambda self: self._branch,
254
225
        doc="""The branch this WorkingTree is connected to.
257
228
            the working tree has been constructed from.
258
229
            """)
259
230
 
 
231
    def has_versioned_directories(self):
 
232
        """See `Tree.has_versioned_directories`."""
 
233
        return self._format.supports_versioned_directories
 
234
 
 
235
    def _supports_executable(self):
 
236
        if sys.platform == 'win32':
 
237
            return False
 
238
        # FIXME: Ideally this should check the file system
 
239
        return True
 
240
 
260
241
    def break_lock(self):
261
242
        """Break a lock if one is present from another instance.
262
243
 
265
246
 
266
247
        This will probe the repository for its lock as well.
267
248
        """
268
 
        self._control_files.break_lock()
269
 
        self.branch.break_lock()
 
249
        raise NotImplementedError(self.break_lock)
270
250
 
271
251
    def requires_rich_root(self):
272
252
        return self._format.requires_rich_root
287
267
        """
288
268
        if path is None:
289
269
            path = osutils.getcwd()
290
 
        control = bzrdir.BzrDir.open(path, _unsupported)
 
270
        control = controldir.ControlDir.open(path, _unsupported)
291
271
        return control.open_workingtree(_unsupported)
292
272
 
293
273
    @staticmethod
305
285
        """
306
286
        if path is None:
307
287
            path = osutils.getcwd()
308
 
        control, relpath = bzrdir.BzrDir.open_containing(path)
 
288
        control, relpath = controldir.ControlDir.open_containing(path)
309
289
        return control.open_workingtree(), relpath
310
290
 
311
291
    @staticmethod
331
311
                if view_files:
332
312
                    file_list = view_files
333
313
                    view_str = views.view_display_str(view_files)
334
 
                    note("Ignoring files outside view. View is %s" % view_str)
 
314
                    note(gettext("Ignoring files outside view. View is %s") % view_str)
335
315
            return tree, file_list
336
316
        if default_directory == u'.':
337
317
            seed = file_list[0]
394
374
            else:
395
375
                return True, tree
396
376
        t = transport.get_transport(location)
397
 
        iterator = bzrdir.BzrDir.find_bzrdirs(t, evaluate=evaluate,
 
377
        iterator = controldir.ControlDir.find_bzrdirs(t, evaluate=evaluate,
398
378
                                              list_current=list_current)
399
379
        return [tr for tr in iterator if tr is not None]
400
380
 
522
502
        raise NotImplementedError(self.get_root_id)
523
503
 
524
504
    @needs_read_lock
525
 
    def clone(self, to_bzrdir, revision_id=None):
 
505
    def clone(self, to_controldir, revision_id=None):
526
506
        """Duplicate this working tree into to_bzr, including all state.
527
507
 
528
508
        Specifically modified files are kept as modified, but
529
509
        ignored and unknown files are discarded.
530
510
 
531
 
        If you want to make a new line of development, see bzrdir.sprout()
 
511
        If you want to make a new line of development, see ControlDir.sprout()
532
512
 
533
513
        revision
534
514
            If not None, the cloned tree will have its last revision set to
536
516
            and this one merged in.
537
517
        """
538
518
        # assumes the target bzr dir format is compatible.
539
 
        result = to_bzrdir.create_workingtree()
 
519
        result = to_controldir.create_workingtree()
540
520
        self.copy_content_into(result, revision_id)
541
521
        return result
542
522
 
550
530
            # TODO now merge from tree.last_revision to revision (to preserve
551
531
            # user local changes)
552
532
            merge.transform_tree(tree, self)
553
 
            tree.set_parent_ids([revision_id])
 
533
            if revision_id == _mod_revision.NULL_REVISION:
 
534
                new_parents = []
 
535
            else:
 
536
                new_parents = [revision_id]
 
537
            tree.set_parent_ids(new_parents)
554
538
 
555
539
    def id2abspath(self, file_id):
556
540
        return self.abspath(self.id2path(file_id))
595
579
            else:
596
580
                return None
597
581
 
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
 
 
602
582
    @needs_tree_write_lock
603
583
    def _gather_kinds(self, files, kinds):
604
584
        """See MutableTree._gather_kinds."""
769
749
 
770
750
    @needs_tree_write_lock
771
751
    def set_merge_modified(self, modified_hashes):
772
 
        def iter_stanzas():
773
 
            for file_id, hash in modified_hashes.iteritems():
774
 
                yield _mod_rio.Stanza(file_id=file_id.decode('utf8'),
775
 
                    hash=hash)
776
 
        self._put_rio('merge-hashes', iter_stanzas(), MERGE_MODIFIED_HEADER_1)
 
752
        """Set the merge modified hashes."""
 
753
        raise NotImplementedError(self.set_merge_modified)
777
754
 
778
755
    def _sha_from_stat(self, path, stat_result):
779
756
        """Get a sha digest from the tree's stat cache.
785
762
        """
786
763
        return None
787
764
 
788
 
    def _put_rio(self, filename, stanzas, header):
789
 
        self._must_be_locked()
790
 
        my_file = _mod_rio.rio_file(stanzas, header)
791
 
        self._transport.put_file(filename, my_file,
792
 
            mode=self.bzrdir._get_file_mode())
793
 
 
794
765
    @needs_write_lock # because merge pulls data into the branch.
795
766
    def merge_from_branch(self, branch, to_revision=None, from_revision=None,
796
767
                          merge_type=None, force=False):
1036
1007
                                show_base=show_base)
1037
1008
                    basis_root_id = basis_tree.get_root_id()
1038
1009
                    new_root_id = new_basis_tree.get_root_id()
1039
 
                    if basis_root_id != new_root_id:
 
1010
                    if new_root_id is not None and basis_root_id != new_root_id:
1040
1011
                        self.set_root_id(new_root_id)
1041
1012
                finally:
1042
1013
                    basis_tree.unlock()
1043
1014
                # TODO - dedup parents list with things merged by pull ?
1044
1015
                # reuse the revisiontree we merged against to set the new
1045
1016
                # tree data.
1046
 
                parent_trees = [(self.branch.last_revision(), new_basis_tree)]
 
1017
                parent_trees = []
 
1018
                if self.branch.last_revision() != _mod_revision.NULL_REVISION:
 
1019
                    parent_trees.append(
 
1020
                        (self.branch.last_revision(), new_basis_tree))
1047
1021
                # we have to pull the merge trees out again, because
1048
1022
                # merge_inner has set the ids. - this corner is not yet
1049
1023
                # layered well enough to prevent double handling.
1066
1040
            stream.write(bytes)
1067
1041
        finally:
1068
1042
            stream.close()
1069
 
        # TODO: update the hashcache here ?
1070
1043
 
1071
1044
    def extras(self):
1072
1045
        """Yield all unversioned files in this WorkingTree.
1149
1122
        else:
1150
1123
            mode = stat_value.st_mode
1151
1124
            kind = osutils.file_kind_from_stat_mode(mode)
1152
 
            if not supports_executable():
 
1125
            if not self._supports_executable():
1153
1126
                executable = entry is not None and entry.executable
1154
1127
            else:
1155
1128
                executable = bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
1174
1147
        return _mod_revision.ensure_null(self.branch.last_revision())
1175
1148
 
1176
1149
    def is_locked(self):
1177
 
        return self._control_files.is_locked()
1178
 
 
1179
 
    def _must_be_locked(self):
1180
 
        if not self.is_locked():
1181
 
            raise errors.ObjectNotLocked(self)
 
1150
        """Check if this tree is locked."""
 
1151
        raise NotImplementedError(self.is_locked)
1182
1152
 
1183
1153
    def lock_read(self):
1184
1154
        """Lock the tree for reading.
1187
1157
 
1188
1158
        :return: A bzrlib.lock.LogicalLockResult.
1189
1159
        """
1190
 
        if not self.is_locked():
1191
 
            self._reset_data()
1192
 
        self.branch.lock_read()
1193
 
        try:
1194
 
            self._control_files.lock_read()
1195
 
            return LogicalLockResult(self.unlock)
1196
 
        except:
1197
 
            self.branch.unlock()
1198
 
            raise
 
1160
        raise NotImplementedError(self.lock_read)
1199
1161
 
1200
1162
    def lock_tree_write(self):
1201
1163
        """See MutableTree.lock_tree_write, and WorkingTree.unlock.
1202
1164
 
1203
1165
        :return: A bzrlib.lock.LogicalLockResult.
1204
1166
        """
1205
 
        if not self.is_locked():
1206
 
            self._reset_data()
1207
 
        self.branch.lock_read()
1208
 
        try:
1209
 
            self._control_files.lock_write()
1210
 
            return LogicalLockResult(self.unlock)
1211
 
        except:
1212
 
            self.branch.unlock()
1213
 
            raise
 
1167
        raise NotImplementedError(self.lock_tree_write)
1214
1168
 
1215
1169
    def lock_write(self):
1216
1170
        """See MutableTree.lock_write, and WorkingTree.unlock.
1217
1171
 
1218
1172
        :return: A bzrlib.lock.LogicalLockResult.
1219
1173
        """
1220
 
        if not self.is_locked():
1221
 
            self._reset_data()
1222
 
        self.branch.lock_write()
1223
 
        try:
1224
 
            self._control_files.lock_write()
1225
 
            return LogicalLockResult(self.unlock)
1226
 
        except:
1227
 
            self.branch.unlock()
1228
 
            raise
 
1174
        raise NotImplementedError(self.lock_write)
1229
1175
 
1230
1176
    def get_physical_lock_status(self):
1231
 
        return self._control_files.get_physical_lock_status()
1232
 
 
1233
 
    def _reset_data(self):
1234
 
        """Reset transient data that cannot be revalidated."""
1235
 
        raise NotImplementedError(self._reset_data)
 
1177
        raise NotImplementedError(self.get_physical_lock_status)
1236
1178
 
1237
1179
    def set_last_revision(self, new_revision):
1238
1180
        """Change the last revision in the working tree."""
1532
1474
                                             show_base=show_base)
1533
1475
            if nb_conflicts:
1534
1476
                self.add_parent_tree((old_tip, other_tree))
1535
 
                note('Rerun update after fixing the conflicts.')
 
1477
                note(gettext('Rerun update after fixing the conflicts.'))
1536
1478
                return nb_conflicts
1537
1479
 
1538
1480
        if last_rev != _mod_revision.ensure_null(revision):
1580
1522
            last_rev = parent_trees[0][0]
1581
1523
        return nb_conflicts
1582
1524
 
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
 
 
1597
1525
    def set_conflicts(self, arg):
1598
1526
        raise errors.UnsupportedOperation(self.set_conflicts, self)
1599
1527
 
1828
1756
        :param branch: A branch to override probing for the branch.
1829
1757
        """
1830
1758
        super(InventoryWorkingTree, self).__init__(basedir=basedir,
1831
 
            branch=branch, _control_files=_control_files, _internal=_internal,
1832
 
            _format=_format, _bzrdir=_bzrdir)
 
1759
            branch=branch, _transport=_control_files._transport,
 
1760
            _internal=_internal, _format=_format, _bzrdir=_bzrdir)
 
1761
 
 
1762
        self._control_files = _control_files
 
1763
        self._detect_case_handling()
1833
1764
 
1834
1765
        if _inventory is None:
1835
1766
            # This will be acquired on lock_read() or lock_write()
1855
1786
        self._inventory = inv
1856
1787
        self._inventory_is_modified = dirty
1857
1788
 
 
1789
    def _detect_case_handling(self):
 
1790
        wt_trans = self.bzrdir.get_workingtree_transport(None)
 
1791
        try:
 
1792
            wt_trans.stat(self._format.case_sensitive_filename)
 
1793
        except errors.NoSuchFile:
 
1794
            self.case_sensitive = True
 
1795
        else:
 
1796
            self.case_sensitive = False
 
1797
 
 
1798
        self._setup_directory_is_tree_reference()
 
1799
 
1858
1800
    def _serialize(self, inventory, out_file):
1859
1801
        xml5.serializer_v5.write_inventory(self._inventory, out_file,
1860
1802
            working=True)
1862
1804
    def _deserialize(selt, in_file):
1863
1805
        return xml5.serializer_v5.read_inventory(in_file)
1864
1806
 
 
1807
    def break_lock(self):
 
1808
        """Break a lock if one is present from another instance.
 
1809
 
 
1810
        Uses the ui factory to ask for confirmation if the lock may be from
 
1811
        an active process.
 
1812
 
 
1813
        This will probe the repository for its lock as well.
 
1814
        """
 
1815
        self._control_files.break_lock()
 
1816
        self.branch.break_lock()
 
1817
 
 
1818
    def is_locked(self):
 
1819
        return self._control_files.is_locked()
 
1820
 
 
1821
    def _must_be_locked(self):
 
1822
        if not self.is_locked():
 
1823
            raise errors.ObjectNotLocked(self)
 
1824
 
 
1825
    def lock_read(self):
 
1826
        """Lock the tree for reading.
 
1827
 
 
1828
        This also locks the branch, and can be unlocked via self.unlock().
 
1829
 
 
1830
        :return: A bzrlib.lock.LogicalLockResult.
 
1831
        """
 
1832
        if not self.is_locked():
 
1833
            self._reset_data()
 
1834
        self.branch.lock_read()
 
1835
        try:
 
1836
            self._control_files.lock_read()
 
1837
            return LogicalLockResult(self.unlock)
 
1838
        except:
 
1839
            self.branch.unlock()
 
1840
            raise
 
1841
 
 
1842
    def lock_tree_write(self):
 
1843
        """See MutableTree.lock_tree_write, and WorkingTree.unlock.
 
1844
 
 
1845
        :return: A bzrlib.lock.LogicalLockResult.
 
1846
        """
 
1847
        if not self.is_locked():
 
1848
            self._reset_data()
 
1849
        self.branch.lock_read()
 
1850
        try:
 
1851
            self._control_files.lock_write()
 
1852
            return LogicalLockResult(self.unlock)
 
1853
        except:
 
1854
            self.branch.unlock()
 
1855
            raise
 
1856
 
 
1857
    def lock_write(self):
 
1858
        """See MutableTree.lock_write, and WorkingTree.unlock.
 
1859
 
 
1860
        :return: A bzrlib.lock.LogicalLockResult.
 
1861
        """
 
1862
        if not self.is_locked():
 
1863
            self._reset_data()
 
1864
        self.branch.lock_write()
 
1865
        try:
 
1866
            self._control_files.lock_write()
 
1867
            return LogicalLockResult(self.unlock)
 
1868
        except:
 
1869
            self.branch.unlock()
 
1870
            raise
 
1871
 
 
1872
    def get_physical_lock_status(self):
 
1873
        return self._control_files.get_physical_lock_status()
 
1874
 
1865
1875
    @needs_tree_write_lock
1866
1876
    def _write_inventory(self, inv):
1867
1877
        """Write inventory as the current inventory."""
2164
2174
            mode=self.bzrdir._get_file_mode())
2165
2175
        self._inventory_is_modified = False
2166
2176
 
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
 
 
2173
2177
    def get_file_mtime(self, file_id, path=None):
2174
2178
        """See Tree.get_file_mtime."""
2175
2179
        if not path:
2176
2180
            path = self.inventory.id2path(file_id)
2177
 
        return os.lstat(self.abspath(path)).st_mtime
 
2181
        try:
 
2182
            return os.lstat(self.abspath(path)).st_mtime
 
2183
        except OSError, e:
 
2184
            if e.errno == errno.ENOENT:
 
2185
                raise errors.FileTimestampUnavailable(path)
 
2186
            raise
2178
2187
 
2179
2188
    def _is_executable_from_path_and_stat_from_basis(self, path, stat_result):
2180
2189
        file_id = self.path2id(path)
2188
2197
        mode = stat_result.st_mode
2189
2198
        return bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
2190
2199
 
2191
 
    if not supports_executable():
2192
 
        def is_executable(self, file_id, path=None):
 
2200
    def is_executable(self, file_id, path=None):
 
2201
        if not self._supports_executable():
2193
2202
            return self._inventory[file_id].executable
2194
 
 
2195
 
        _is_executable_from_path_and_stat = \
2196
 
            _is_executable_from_path_and_stat_from_basis
2197
 
    else:
2198
 
        def is_executable(self, file_id, path=None):
 
2203
        else:
2199
2204
            if not path:
2200
2205
                path = self.id2path(file_id)
2201
2206
            mode = os.lstat(self.abspath(path)).st_mode
2202
2207
            return bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
2203
2208
 
2204
 
        _is_executable_from_path_and_stat = \
2205
 
            _is_executable_from_path_and_stat_from_stat
 
2209
    def _is_executable_from_path_and_stat(self, path, stat_result):
 
2210
        if not self._supports_executable():
 
2211
            return self._is_executable_from_path_and_stat_from_basis(path, stat_result)
 
2212
        else:
 
2213
            return self._is_executable_from_path_and_stat_from_stat(path, stat_result)
2206
2214
 
2207
2215
    @needs_tree_write_lock
2208
2216
    def _add(self, files, ids, kinds):
2287
2295
                       for key, line in annotator.annotate_flat(this_key)]
2288
2296
        return annotations
2289
2297
 
 
2298
    def _put_rio(self, filename, stanzas, header):
 
2299
        self._must_be_locked()
 
2300
        my_file = _mod_rio.rio_file(stanzas, header)
 
2301
        self._transport.put_file(filename, my_file,
 
2302
            mode=self.bzrdir._get_file_mode())
 
2303
 
 
2304
    @needs_tree_write_lock
 
2305
    def set_merge_modified(self, modified_hashes):
 
2306
        def iter_stanzas():
 
2307
            for file_id, hash in modified_hashes.iteritems():
 
2308
                yield _mod_rio.Stanza(file_id=file_id.decode('utf8'),
 
2309
                    hash=hash)
 
2310
        self._put_rio('merge-hashes', iter_stanzas(), MERGE_MODIFIED_HEADER_1)
 
2311
 
2290
2312
    @needs_read_lock
2291
2313
    def merge_modified(self):
2292
2314
        """Return a dictionary of files modified by a merge.
2782
2804
                # something is wrong, so lets determine what exactly
2783
2805
                if not self.has_filename(from_rel) and \
2784
2806
                   not self.has_filename(to_rel):
2785
 
                    raise errors.BzrRenameFailedError(from_rel,to_rel,
2786
 
                        errors.PathsDoNotExist(paths=(str(from_rel),
2787
 
                        str(to_rel))))
 
2807
                    raise errors.BzrRenameFailedError(from_rel, to_rel,
 
2808
                        errors.PathsDoNotExist(paths=(from_rel, to_rel)))
2788
2809
                else:
2789
2810
                    raise errors.RenameFailedFilesExist(from_rel, to_rel)
2790
2811
            rename_entry.only_change_inv = only_change_inv
3016
3037
 
3017
3038
    supports_versioned_directories = None
3018
3039
 
3019
 
    @classmethod
3020
 
    def find_format_string(klass, a_bzrdir):
3021
 
        """Return format name for the working tree object in a_bzrdir."""
3022
 
        try:
3023
 
            transport = a_bzrdir.get_workingtree_transport(None)
3024
 
            return transport.get_bytes("format")
3025
 
        except errors.NoSuchFile:
3026
 
            raise errors.NoWorkingTree(base=transport.base)
3027
 
 
3028
 
    @classmethod
3029
 
    def find_format(klass, a_bzrdir):
3030
 
        """Return the format for the working tree object in a_bzrdir."""
3031
 
        try:
3032
 
            format_string = klass.find_format_string(a_bzrdir)
3033
 
            return format_registry.get(format_string)
3034
 
        except KeyError:
3035
 
            raise errors.UnknownFormatError(format=format_string,
3036
 
                                            kind="working tree")
3037
 
 
3038
 
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
 
3040
    def initialize(self, controldir, revision_id=None, from_branch=None,
3039
3041
                   accelerator_tree=None, hardlink=False):
3040
 
        """Initialize a new working tree in a_bzrdir.
 
3042
        """Initialize a new working tree in controldir.
3041
3043
 
3042
 
        :param a_bzrdir: BzrDir to initialize the working tree in.
 
3044
        :param controldir: ControlDir to initialize the working tree in.
3043
3045
        :param revision_id: allows creating a working tree at a different
3044
3046
            revision than the branch is at.
3045
3047
        :param from_branch: Branch to checkout
3065
3067
        """Return the current default format."""
3066
3068
        return format_registry.get_default()
3067
3069
 
3068
 
    def get_format_string(self):
3069
 
        """Return the ASCII format string that identifies this format."""
3070
 
        raise NotImplementedError(self.get_format_string)
3071
 
 
3072
3070
    def get_format_description(self):
3073
3071
        """Return the short description for this format."""
3074
3072
        raise NotImplementedError(self.get_format_description)
3126
3124
    def unregister_format(klass, format):
3127
3125
        format_registry.remove(format)
3128
3126
 
 
3127
    def get_controldir_for_branch(self):
 
3128
        """Get the control directory format for creating branches.
 
3129
 
 
3130
        This is to support testing of working tree formats that can not exist
 
3131
        in the same control directory as a branch.
 
3132
        """
 
3133
        return self._matchingbzrdir
 
3134
 
 
3135
 
 
3136
class WorkingTreeFormatMetaDir(bzrdir.BzrDirMetaComponentFormat, WorkingTreeFormat):
 
3137
    """Base class for working trees that live in bzr meta directories."""
 
3138
 
 
3139
    def __init__(self):
 
3140
        WorkingTreeFormat.__init__(self)
 
3141
        bzrdir.BzrDirMetaComponentFormat.__init__(self)
 
3142
 
 
3143
    @classmethod
 
3144
    def find_format_string(klass, controldir):
 
3145
        """Return format name for the working tree object in controldir."""
 
3146
        try:
 
3147
            transport = controldir.get_workingtree_transport(None)
 
3148
            return transport.get_bytes("format")
 
3149
        except errors.NoSuchFile:
 
3150
            raise errors.NoWorkingTree(base=transport.base)
 
3151
 
 
3152
    @classmethod
 
3153
    def find_format(klass, controldir):
 
3154
        """Return the format for the working tree object in controldir."""
 
3155
        format_string = klass.find_format_string(controldir)
 
3156
        return klass._find_format(format_registry, 'working tree',
 
3157
                format_string)
 
3158
 
3129
3159
 
3130
3160
format_registry.register_lazy("Bazaar Working Tree Format 4 (bzr 0.15)\n",
3131
3161
    "bzrlib.workingtree_4", "WorkingTreeFormat4")