72
# Explicitly import bzrlib.bzrdir so that the BzrProber
73
# is guaranteed to be registered.
72
from bzrlib import symbol_versioning
79
73
from bzrlib.decorators import needs_read_lock, needs_write_lock
80
74
from bzrlib.i18n import gettext
81
75
from bzrlib.lock import LogicalLockResult
198
193
self._branch = self.bzrdir.open_branch()
199
194
self.basedir = realpath(basedir)
200
self._transport = _transport
195
self._control_files = _control_files
196
self._transport = self._control_files._transport
201
197
self._rules_searcher = None
202
198
self.views = self._make_views()
233
229
"""See `Tree.has_versioned_directories`."""
234
230
return self._format.supports_versioned_directories
236
def _supports_executable(self):
237
if sys.platform == 'win32':
239
# FIXME: Ideally this should check the file system
242
232
def break_lock(self):
243
233
"""Break a lock if one is present from another instance.
248
238
This will probe the repository for its lock as well.
250
raise NotImplementedError(self.break_lock)
240
self._control_files.break_lock()
241
self.branch.break_lock()
252
243
def requires_rich_root(self):
253
244
return self._format.requires_rich_root
261
252
def supports_views(self):
262
253
return self.views.supports_views()
264
def get_config_stack(self):
265
"""Retrieve the config stack for this tree.
267
:return: A ``bzrlib.config.Stack``
269
# For the moment, just provide the branch config stack.
270
return self.branch.get_config_stack()
273
256
def open(path=None, _unsupported=False):
274
257
"""Open an existing working tree at path.
278
261
path = osutils.getcwd()
279
control = controldir.ControlDir.open(path, _unsupported=_unsupported)
280
return control.open_workingtree(unsupported=_unsupported)
262
control = controldir.ControlDir.open(path, _unsupported)
263
return control.open_workingtree(_unsupported)
283
266
def open_containing(path=None):
387
370
list_current=list_current)
388
371
return [tr for tr in iterator if tr is not None]
373
def all_file_ids(self):
374
"""See Tree.iter_all_file_ids"""
375
raise NotImplementedError(self.all_file_ids)
390
377
def __repr__(self):
391
378
return "<%s of %s>" % (self.__class__.__name__,
392
379
getattr(self, 'basedir', None))
755
742
@needs_tree_write_lock
756
743
def set_merge_modified(self, modified_hashes):
757
"""Set the merge modified hashes."""
758
raise NotImplementedError(self.set_merge_modified)
745
for file_id, hash in modified_hashes.iteritems():
746
yield _mod_rio.Stanza(file_id=file_id.decode('utf8'),
748
self._put_rio('merge-hashes', iter_stanzas(), MERGE_MODIFIED_HEADER_1)
760
750
def _sha_from_stat(self, path, stat_result):
761
751
"""Get a sha digest from the tree's stat cache.
760
def _put_rio(self, filename, stanzas, header):
761
self._must_be_locked()
762
my_file = _mod_rio.rio_file(stanzas, header)
763
self._transport.put_file(filename, my_file,
764
mode=self.bzrdir._get_file_mode())
770
766
@needs_write_lock # because merge pulls data into the branch.
771
767
def merge_from_branch(self, branch, to_revision=None, from_revision=None,
772
768
merge_type=None, force=False):
1128
1124
mode = stat_value.st_mode
1129
1125
kind = osutils.file_kind_from_stat_mode(mode)
1130
if not self._supports_executable():
1126
if not supports_executable():
1131
1127
executable = entry is not None and entry.executable
1133
1129
executable = bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
1152
1148
return _mod_revision.ensure_null(self.branch.last_revision())
1154
1150
def is_locked(self):
1155
"""Check if this tree is locked."""
1156
raise NotImplementedError(self.is_locked)
1151
return self._control_files.is_locked()
1153
def _must_be_locked(self):
1154
if not self.is_locked():
1155
raise errors.ObjectNotLocked(self)
1158
1157
def lock_read(self):
1159
1158
"""Lock the tree for reading.
1163
1162
:return: A bzrlib.lock.LogicalLockResult.
1165
raise NotImplementedError(self.lock_read)
1164
if not self.is_locked():
1166
self.branch.lock_read()
1168
self._control_files.lock_read()
1169
return LogicalLockResult(self.unlock)
1171
self.branch.unlock()
1167
1174
def lock_tree_write(self):
1168
1175
"""See MutableTree.lock_tree_write, and WorkingTree.unlock.
1170
1177
:return: A bzrlib.lock.LogicalLockResult.
1172
raise NotImplementedError(self.lock_tree_write)
1179
if not self.is_locked():
1181
self.branch.lock_read()
1183
self._control_files.lock_write()
1184
return LogicalLockResult(self.unlock)
1186
self.branch.unlock()
1174
1189
def lock_write(self):
1175
1190
"""See MutableTree.lock_write, and WorkingTree.unlock.
1177
1192
:return: A bzrlib.lock.LogicalLockResult.
1179
raise NotImplementedError(self.lock_write)
1194
if not self.is_locked():
1196
self.branch.lock_write()
1198
self._control_files.lock_write()
1199
return LogicalLockResult(self.unlock)
1201
self.branch.unlock()
1181
1204
def get_physical_lock_status(self):
1182
raise NotImplementedError(self.get_physical_lock_status)
1205
return self._control_files.get_physical_lock_status()
1207
def _reset_data(self):
1208
"""Reset transient data that cannot be revalidated."""
1209
raise NotImplementedError(self._reset_data)
1184
1211
def set_last_revision(self, new_revision):
1185
1212
"""Change the last revision in the working tree."""
1761
1788
:param branch: A branch to override probing for the branch.
1763
1790
super(InventoryWorkingTree, self).__init__(basedir=basedir,
1764
branch=branch, _transport=_control_files._transport,
1765
_internal=_internal, _format=_format, _bzrdir=_bzrdir)
1791
branch=branch, _control_files=_control_files, _internal=_internal,
1792
_format=_format, _bzrdir=_bzrdir)
1767
self._control_files = _control_files
1768
1794
self._detect_case_handling()
1770
1796
if _inventory is None:
1809
1835
def _deserialize(selt, in_file):
1810
1836
return xml5.serializer_v5.read_inventory(in_file)
1812
def break_lock(self):
1813
"""Break a lock if one is present from another instance.
1815
Uses the ui factory to ask for confirmation if the lock may be from
1818
This will probe the repository for its lock as well.
1820
self._control_files.break_lock()
1821
self.branch.break_lock()
1823
def is_locked(self):
1824
return self._control_files.is_locked()
1826
def _must_be_locked(self):
1827
if not self.is_locked():
1828
raise errors.ObjectNotLocked(self)
1830
def lock_read(self):
1831
"""Lock the tree for reading.
1833
This also locks the branch, and can be unlocked via self.unlock().
1835
:return: A bzrlib.lock.LogicalLockResult.
1837
if not self.is_locked():
1839
self.branch.lock_read()
1841
self._control_files.lock_read()
1842
return LogicalLockResult(self.unlock)
1844
self.branch.unlock()
1847
def lock_tree_write(self):
1848
"""See MutableTree.lock_tree_write, and WorkingTree.unlock.
1850
:return: A bzrlib.lock.LogicalLockResult.
1852
if not self.is_locked():
1854
self.branch.lock_read()
1856
self._control_files.lock_write()
1857
return LogicalLockResult(self.unlock)
1859
self.branch.unlock()
1862
def lock_write(self):
1863
"""See MutableTree.lock_write, and WorkingTree.unlock.
1865
:return: A bzrlib.lock.LogicalLockResult.
1867
if not self.is_locked():
1869
self.branch.lock_write()
1871
self._control_files.lock_write()
1872
return LogicalLockResult(self.unlock)
1874
self.branch.unlock()
1877
def get_physical_lock_status(self):
1878
return self._control_files.get_physical_lock_status()
1880
1838
@needs_tree_write_lock
1881
1839
def _write_inventory(self, inv):
1882
1840
"""Write inventory as the current inventory."""
1950
1908
if entry.parent_id == orig_root_id:
1951
1909
entry.parent_id = inv.root.file_id
1911
def all_file_ids(self):
1912
"""See Tree.iter_all_file_ids"""
1913
return set(self.inventory)
1953
1915
@needs_tree_write_lock
1954
1916
def set_parent_trees(self, parents_list, allow_leftmost_as_ghost=False):
1955
1917
"""See MutableTree.set_parent_trees."""
1974
1936
# parent tree from the repository.
1975
1937
self._cache_basis_inventory(leftmost_parent_id)
1977
inv = leftmost_parent_tree.root_inventory
1939
inv = leftmost_parent_tree.inventory
1978
1940
xml = self._create_basis_xml_from_inventory(
1979
1941
leftmost_parent_id, inv)
1980
1942
self._write_basis_inventory(xml)
2078
2040
def has_id(self, file_id):
2079
2041
# files that have been deleted are excluded
2080
inv, inv_file_id = self._unpack_file_id(file_id)
2081
if not inv.has_id(inv_file_id):
2042
inv = self.inventory
2043
if not inv.has_id(file_id):
2083
path = inv.id2path(inv_file_id)
2045
path = inv.id2path(file_id)
2084
2046
return osutils.lexists(self.abspath(path))
2086
2048
def has_or_had_id(self, file_id):
2087
if file_id == self.get_root_id():
2049
if file_id == self.inventory.root.file_id:
2089
inv, inv_file_id = self._unpack_file_id(file_id)
2090
return inv.has_id(inv_file_id)
2051
return self.inventory.has_id(file_id)
2092
def all_file_ids(self):
2053
@symbol_versioning.deprecated_method(symbol_versioning.deprecated_in((2, 4, 0)))
2093
2055
"""Iterate through file_ids for this tree.
2095
2057
file_ids are in a WorkingTree if they are in the working inventory
2096
2058
and the working file exists.
2099
for path, ie in self.iter_entries_by_dir():
2060
inv = self._inventory
2061
for path, ie in inv.iter_entries():
2062
if osutils.lexists(self.abspath(path)):
2103
2065
@needs_tree_write_lock
2104
2066
def set_last_revision(self, new_revision):
2160
2122
_mod_revision.NULL_REVISION)
2162
2124
rt = self.branch.repository.revision_tree(revision_ids[0])
2163
self._write_inventory(rt.root_inventory)
2125
self._write_inventory(rt.inventory)
2164
2126
self.set_parent_ids(revision_ids)
2166
2128
def flush(self):
2178
2140
def get_file_mtime(self, file_id, path=None):
2179
2141
"""See Tree.get_file_mtime."""
2181
path = self.id2path(file_id)
2143
path = self.inventory.id2path(file_id)
2183
2145
return os.lstat(self.abspath(path)).st_mtime
2184
2146
except OSError, e:
2189
2151
def _is_executable_from_path_and_stat_from_basis(self, path, stat_result):
2190
inv, file_id = self._path2inv_file_id(path)
2152
file_id = self.path2id(path)
2191
2153
if file_id is None:
2192
2154
# For unversioned files on win32, we just assume they are not
2195
return inv[file_id].executable
2157
return self._inventory[file_id].executable
2197
2159
def _is_executable_from_path_and_stat_from_stat(self, path, stat_result):
2198
2160
mode = stat_result.st_mode
2199
2161
return bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
2201
def is_executable(self, file_id, path=None):
2202
if not self._supports_executable():
2203
inv, inv_file_id = self._unpack_file_id(file_id)
2204
return inv[inv_file_id].executable
2163
if not supports_executable():
2164
def is_executable(self, file_id, path=None):
2165
return self._inventory[file_id].executable
2167
_is_executable_from_path_and_stat = \
2168
_is_executable_from_path_and_stat_from_basis
2170
def is_executable(self, file_id, path=None):
2207
2172
path = self.id2path(file_id)
2208
2173
mode = os.lstat(self.abspath(path)).st_mode
2209
2174
return bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
2211
def _is_executable_from_path_and_stat(self, path, stat_result):
2212
if not self._supports_executable():
2213
return self._is_executable_from_path_and_stat_from_basis(path, stat_result)
2215
return self._is_executable_from_path_and_stat_from_stat(path, stat_result)
2176
_is_executable_from_path_and_stat = \
2177
_is_executable_from_path_and_stat_from_stat
2217
2179
@needs_tree_write_lock
2218
2180
def _add(self, files, ids, kinds):
2221
2183
# should probably put it back with the previous ID.
2222
2184
# the read and write working inventory should not occur in this
2223
2185
# function - they should be part of lock_write and unlock.
2224
# FIXME: nested trees
2225
inv = self.root_inventory
2186
inv = self.inventory
2226
2187
for f, file_id, kind in zip(files, ids, kinds):
2227
2188
if file_id is None:
2228
2189
inv.add_path(f, kind=kind)
2269
2230
parent_tree = self.branch.repository.revision_tree(parent_id)
2270
2231
parent_tree.lock_read()
2273
kind = parent_tree.kind(file_id)
2274
except errors.NoSuchId:
2233
if not parent_tree.has_id(file_id):
2235
ie = parent_tree.inventory[file_id]
2236
if ie.kind != 'file':
2277
2237
# Note: this is slightly unnecessary, because symlinks and
2278
2238
# directories have a "text" which is the empty text, and we
2279
2239
# know that won't mess up annotations. But it seems cleaner
2282
file_id, parent_tree.get_file_revision(file_id))
2241
parent_text_key = (file_id, ie.revision)
2283
2242
if parent_text_key not in maybe_file_parent_keys:
2284
2243
maybe_file_parent_keys.append(parent_text_key)
2300
2259
for key, line in annotator.annotate_flat(this_key)]
2301
2260
return annotations
2303
def _put_rio(self, filename, stanzas, header):
2304
self._must_be_locked()
2305
my_file = _mod_rio.rio_file(stanzas, header)
2306
self._transport.put_file(filename, my_file,
2307
mode=self.bzrdir._get_file_mode())
2309
@needs_tree_write_lock
2310
def set_merge_modified(self, modified_hashes):
2312
for file_id, hash in modified_hashes.iteritems():
2313
yield _mod_rio.Stanza(file_id=file_id.decode('utf8'),
2315
self._put_rio('merge-hashes', iter_stanzas(), MERGE_MODIFIED_HEADER_1)
2317
2262
@needs_read_lock
2318
2263
def merge_modified(self):
2319
2264
"""Return a dictionary of files modified by a merge.
2339
2284
for s in _mod_rio.RioReader(hashfile):
2340
2285
# RioReader reads in Unicode, so convert file_ids back to utf8
2341
2286
file_id = osutils.safe_file_id(s.get("file_id"), warn=False)
2342
if not self.has_id(file_id):
2287
if not self.inventory.has_id(file_id):
2344
2289
text_hash = s.get("hash")
2345
2290
if text_hash == self.get_file_sha1(file_id):
2375
2320
other_tree.lock_tree_write()
2377
2322
new_parents = other_tree.get_parent_ids()
2378
other_root = other_tree.root_inventory.root
2323
other_root = other_tree.inventory.root
2379
2324
other_root.parent_id = new_root_parent
2380
2325
other_root.name = osutils.basename(other_tree_path)
2381
self.root_inventory.add(other_root)
2382
add_children(self.root_inventory, other_root)
2383
self._write_inventory(self.root_inventory)
2326
self.inventory.add(other_root)
2327
add_children(self.inventory, other_root)
2328
self._write_inventory(self.inventory)
2384
2329
# normally we don't want to fetch whole repositories, but i think
2385
2330
# here we really do want to consolidate the whole thing.
2386
2331
for parent_id in other_tree.get_parent_ids():
2424
2369
tree_transport = self.bzrdir.root_transport.clone(sub_path)
2425
2370
if tree_transport.base != branch_transport.base:
2426
2371
tree_bzrdir = format.initialize_on_transport(tree_transport)
2427
tree_bzrdir.set_branch_reference(new_branch)
2372
branch.BranchReferenceFormat().initialize(tree_bzrdir,
2373
target_branch=new_branch)
2429
2375
tree_bzrdir = branch_bzrdir
2430
2376
wt = tree_bzrdir.create_workingtree(_mod_revision.NULL_REVISION)
2431
2377
wt.set_parent_ids(self.get_parent_ids())
2432
# FIXME: Support nested trees
2433
my_inv = self.root_inventory
2378
my_inv = self.inventory
2434
2379
child_inv = inventory.Inventory(root_id=None)
2435
2380
new_root = my_inv[file_id]
2436
2381
my_inv.remove_recursive_id(file_id)
2456
2401
if not self.is_locked():
2457
2402
raise errors.ObjectNotLocked(self)
2404
inv = self.inventory
2459
2405
if from_dir is None and include_root is True:
2460
yield ('', 'V', 'directory', self.get_root_id(), self.root_inventory.root)
2406
yield ('', 'V', 'directory', inv.root.file_id, inv.root)
2461
2407
# Convert these into local objects to save lookup times
2462
2408
pathjoin = osutils.pathjoin
2463
2409
file_kind = self._kind
2471
2417
# directory file_id, relative path, absolute path, reverse sorted children
2472
2418
if from_dir is not None:
2473
inv, from_dir_id = self._path2inv_file_id(from_dir)
2419
from_dir_id = inv.path2id(from_dir)
2474
2420
if from_dir_id is None:
2475
2421
# Directory not versioned
2477
2423
from_dir_abspath = pathjoin(self.basedir, from_dir)
2479
inv = self.root_inventory
2480
2425
from_dir_id = inv.root.file_id
2481
2426
from_dir_abspath = self.basedir
2482
2427
children = os.listdir(from_dir_abspath)
2605
2550
rename_entries = []
2606
2551
rename_tuples = []
2608
invs_to_write = set()
2610
2553
# check for deprecated use of signature
2611
2554
if to_dir is None:
2612
2555
raise TypeError('You must supply a target directory')
2613
2556
# check destination directory
2614
2557
if isinstance(from_paths, basestring):
2615
2558
raise ValueError()
2559
inv = self.inventory
2616
2560
to_abs = self.abspath(to_dir)
2617
2561
if not isdir(to_abs):
2618
2562
raise errors.BzrMoveFailedError('',to_dir,
2620
2564
if not self.has_filename(to_dir):
2621
2565
raise errors.BzrMoveFailedError('',to_dir,
2622
2566
errors.NotInWorkingDirectory(to_dir))
2623
to_inv, to_dir_id = self._path2inv_file_id(to_dir)
2567
to_dir_id = inv.path2id(to_dir)
2624
2568
if to_dir_id is None:
2625
2569
raise errors.BzrMoveFailedError('',to_dir,
2626
2570
errors.NotVersionedError(path=to_dir))
2628
to_dir_ie = to_inv[to_dir_id]
2572
to_dir_ie = inv[to_dir_id]
2629
2573
if to_dir_ie.kind != 'directory':
2630
2574
raise errors.BzrMoveFailedError('',to_dir,
2631
2575
errors.NotADirectory(to_abs))
2633
2577
# create rename entries and tuples
2634
2578
for from_rel in from_paths:
2635
2579
from_tail = splitpath(from_rel)[-1]
2636
from_inv, from_id = self._path2inv_file_id(from_rel)
2580
from_id = inv.path2id(from_rel)
2637
2581
if from_id is None:
2638
2582
raise errors.BzrMoveFailedError(from_rel,to_dir,
2639
2583
errors.NotVersionedError(path=from_rel))
2641
from_entry = from_inv[from_id]
2585
from_entry = inv[from_id]
2642
2586
from_parent_id = from_entry.parent_id
2643
2587
to_rel = pathjoin(to_dir, from_tail)
2644
2588
rename_entry = InventoryWorkingTree._RenameEntry(
2663
2607
# restore the inventory on error
2664
2608
self._inventory_is_modified = original_modified
2666
#FIXME: Should potentially also write the from_invs
2667
self._write_inventory(to_inv)
2610
self._write_inventory(inv)
2668
2611
return rename_tuples
2670
2613
@needs_tree_write_lock
2691
2634
Everything else results in an error.
2636
inv = self.inventory
2693
2637
rename_entries = []
2695
2639
# create rename entries and tuples
2696
2640
from_tail = splitpath(from_rel)[-1]
2697
from_inv, from_id = self._path2inv_file_id(from_rel)
2641
from_id = inv.path2id(from_rel)
2698
2642
if from_id is None:
2699
2643
# if file is missing in the inventory maybe it's in the basis_tree
2700
2644
basis_tree = self.branch.basis_tree()
2703
2647
raise errors.BzrRenameFailedError(from_rel,to_rel,
2704
2648
errors.NotVersionedError(path=from_rel))
2705
2649
# put entry back in the inventory so we can rename it
2706
from_entry = basis_tree.root_inventory[from_id].copy()
2707
from_inv.add(from_entry)
2650
from_entry = basis_tree.inventory[from_id].copy()
2709
from_inv, from_inv_id = self._unpack_file_id(from_id)
2710
from_entry = from_inv[from_inv_id]
2653
from_entry = inv[from_id]
2711
2654
from_parent_id = from_entry.parent_id
2712
2655
to_dir, to_tail = os.path.split(to_rel)
2713
to_inv, to_dir_id = self._path2inv_file_id(to_dir)
2656
to_dir_id = inv.path2id(to_dir)
2714
2657
rename_entry = InventoryWorkingTree._RenameEntry(from_rel=from_rel,
2715
2658
from_id=from_id,
2716
2659
from_tail=from_tail,
2738
2681
from_id, from_rel, to_rel, to_dir, to_dir_id)
2740
2683
self._move(rename_entries)
2741
self._write_inventory(to_inv)
2684
self._write_inventory(inv)
2743
2686
class _RenameEntry(object):
2744
2687
def __init__(self, from_rel, from_id, from_tail, from_parent_id,
2761
2704
Also does basic plausability tests.
2763
# FIXME: Handling of nested trees
2764
inv = self.root_inventory
2706
inv = self.inventory
2766
2708
for rename_entry in rename_entries:
2767
2709
# store to local variables for easier reference
2812
2754
# something is wrong, so lets determine what exactly
2813
2755
if not self.has_filename(from_rel) and \
2814
2756
not self.has_filename(to_rel):
2815
raise errors.BzrRenameFailedError(from_rel, to_rel,
2816
errors.PathsDoNotExist(paths=(from_rel, to_rel)))
2757
raise errors.BzrRenameFailedError(from_rel,to_rel,
2758
errors.PathsDoNotExist(paths=(str(from_rel),
2818
2761
raise errors.RenameFailedFilesExist(from_rel, to_rel)
2819
2762
rename_entry.only_change_inv = only_change_inv
2851
2796
" Error message is: %s" % e)
2853
2798
def _move_entry(self, entry):
2854
inv = self.root_inventory
2799
inv = self.inventory
2855
2800
from_rel_abs = self.abspath(entry.from_rel)
2856
2801
to_rel_abs = self.abspath(entry.to_rel)
2857
2802
if from_rel_abs == to_rel_abs:
2899
2844
def stored_kind(self, file_id):
2900
2845
"""See Tree.stored_kind"""
2901
inv, inv_file_id = self._unpack_file_id(file_id)
2902
return inv[inv_file_id].kind
2846
return self.inventory[file_id].kind
2904
2848
def extras(self):
2905
2849
"""Yield all unversioned files in this WorkingTree.
2912
2856
This is the same order used by 'osutils.walkdirs'.
2914
2858
## TODO: Work from given directory downwards
2915
for path, dir_entry in self.iter_entries_by_dir():
2916
if dir_entry.kind != 'directory':
2859
for path, dir_entry in self.inventory.directories():
2918
2860
# mutter("search for unknowns in %r", path)
2919
2861
dirabs = self.abspath(path)
2920
2862
if not isdir(dirabs):
2984
2927
if dir[2] == _directory:
2985
2928
pending.append(dir)
2988
def update_feature_flags(self, updated_flags):
2989
"""Update the feature flags for this branch.
2991
:param updated_flags: Dictionary mapping feature names to necessities
2992
A necessity can be None to indicate the feature should be removed
2994
self._format._update_feature_flags(updated_flags)
2995
self.control_transport.put_bytes('format', self._format.as_string())
2998
2931
class WorkingTreeFormatRegistry(controldir.ControlComponentFormatRegistry):
2999
2932
"""Registry for working tree formats."""
3056
2989
supports_versioned_directories = None
2992
def find_format_string(klass, controldir):
2993
"""Return format name for the working tree object in controldir."""
2995
transport = controldir.get_workingtree_transport(None)
2996
return transport.get_bytes("format")
2997
except errors.NoSuchFile:
2998
raise errors.NoWorkingTree(base=transport.base)
3001
def find_format(klass, controldir):
3002
"""Return the format for the working tree object in controldir."""
3004
format_string = klass.find_format_string(controldir)
3005
return format_registry.get(format_string)
3007
raise errors.UnknownFormatError(format=format_string,
3008
kind="working tree")
3058
3010
def initialize(self, controldir, revision_id=None, from_branch=None,
3059
3011
accelerator_tree=None, hardlink=False):
3060
3012
"""Initialize a new working tree in controldir.
3085
3037
"""Return the current default format."""
3086
3038
return format_registry.get_default()
3040
def get_format_string(self):
3041
"""Return the ASCII format string that identifies this format."""
3042
raise NotImplementedError(self.get_format_string)
3088
3044
def get_format_description(self):
3089
3045
"""Return the short description for this format."""
3090
3046
raise NotImplementedError(self.get_format_description)
3151
3107
return self._matchingbzrdir
3154
class WorkingTreeFormatMetaDir(bzrdir.BzrFormat, WorkingTreeFormat):
3155
"""Base class for working trees that live in bzr meta directories."""
3158
WorkingTreeFormat.__init__(self)
3159
bzrdir.BzrFormat.__init__(self)
3162
def find_format_string(klass, controldir):
3163
"""Return format name for the working tree object in controldir."""
3165
transport = controldir.get_workingtree_transport(None)
3166
return transport.get_bytes("format")
3167
except errors.NoSuchFile:
3168
raise errors.NoWorkingTree(base=transport.base)
3171
def find_format(klass, controldir):
3172
"""Return the format for the working tree object in controldir."""
3173
format_string = klass.find_format_string(controldir)
3174
return klass._find_format(format_registry, 'working tree',
3177
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
3179
WorkingTreeFormat.check_support_status(self,
3180
allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
3182
bzrdir.BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
3183
recommend_upgrade=recommend_upgrade, basedir=basedir)
3186
3110
format_registry.register_lazy("Bazaar Working Tree Format 4 (bzr 0.15)\n",
3187
3111
"bzrlib.workingtree_4", "WorkingTreeFormat4")
3188
3112
format_registry.register_lazy("Bazaar Working Tree Format 5 (bzr 1.11)\n",