73
from bzrlib import symbol_versioning
72
# Explicitly import bzrlib.bzrdir so that the BzrProber
73
# is guaranteed to be registered.
74
79
from bzrlib.decorators import needs_read_lock, needs_write_lock
80
from bzrlib.i18n import gettext
75
81
from bzrlib.lock import LogicalLockResult
76
82
import bzrlib.mutabletree
77
83
from bzrlib.mutabletree import needs_tree_write_lock
173
178
def __init__(self, basedir='.',
174
179
branch=DEPRECATED_PARAMETER,
179
184
"""Construct a WorkingTree instance. This is not a public API.
193
198
self._branch = self.bzrdir.open_branch()
194
199
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
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())
210
# is this scan needed ? it makes things kinda slow.
217
self._detect_case_handling()
200
self._transport = _transport
218
201
self._rules_searcher = None
219
202
self.views = self._make_views()
239
222
return self.bzrdir.is_control_filename(filename)
241
def _detect_case_handling(self):
242
wt_trans = self.bzrdir.get_workingtree_transport(None)
244
wt_trans.stat(self._format.case_sensitive_filename)
245
except errors.NoSuchFile:
246
self.case_sensitive = True
248
self.case_sensitive = False
250
self._setup_directory_is_tree_reference()
252
224
branch = property(
253
225
fget=lambda self: self._branch,
254
226
doc="""The branch this WorkingTree is connected to.
257
229
the working tree has been constructed from.
232
def has_versioned_directories(self):
233
"""See `Tree.has_versioned_directories`."""
234
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
260
242
def break_lock(self):
261
243
"""Break a lock if one is present from another instance.
266
248
This will probe the repository for its lock as well.
268
self._control_files.break_lock()
269
self.branch.break_lock()
250
raise NotImplementedError(self.break_lock)
271
252
def requires_rich_root(self):
272
253
return self._format.requires_rich_root
289
270
path = osutils.getcwd()
290
control = bzrdir.BzrDir.open(path, _unsupported)
291
return control.open_workingtree(_unsupported)
271
control = controldir.ControlDir.open(path, _unsupported=_unsupported)
272
return control.open_workingtree(unsupported=_unsupported)
294
275
def open_containing(path=None):
307
288
path = osutils.getcwd()
308
control, relpath = bzrdir.BzrDir.open_containing(path)
289
control, relpath = controldir.ControlDir.open_containing(path)
309
290
return control.open_workingtree(), relpath
395
376
return True, tree
396
377
t = transport.get_transport(location)
397
iterator = bzrdir.BzrDir.find_bzrdirs(t, evaluate=evaluate,
378
iterator = controldir.ControlDir.find_bzrdirs(t, evaluate=evaluate,
398
379
list_current=list_current)
399
380
return [tr for tr in iterator if tr is not None]
499
def _get_ancestors(self, default_revision):
500
ancestors = set([default_revision])
501
for parent_id in self.get_parent_ids():
502
ancestors.update(self.branch.repository.get_ancestry(
503
parent_id, topo_sorted=False))
506
480
def get_parent_ids(self):
507
481
"""See Tree.get_parent_ids.
529
503
raise NotImplementedError(self.get_root_id)
532
def clone(self, to_bzrdir, revision_id=None):
506
def clone(self, to_controldir, revision_id=None):
533
507
"""Duplicate this working tree into to_bzr, including all state.
535
509
Specifically modified files are kept as modified, but
536
510
ignored and unknown files are discarded.
538
If you want to make a new line of development, see bzrdir.sprout()
512
If you want to make a new line of development, see ControlDir.sprout()
541
515
If not None, the cloned tree will have its last revision set to
543
517
and this one merged in.
545
519
# assumes the target bzr dir format is compatible.
546
result = to_bzrdir.create_workingtree()
520
result = to_controldir.create_workingtree()
547
521
self.copy_content_into(result, revision_id)
557
531
# TODO now merge from tree.last_revision to revision (to preserve
558
532
# user local changes)
559
533
merge.transform_tree(tree, self)
560
tree.set_parent_ids([revision_id])
534
if revision_id == _mod_revision.NULL_REVISION:
537
new_parents = [revision_id]
538
tree.set_parent_ids(new_parents)
562
540
def id2abspath(self, file_id):
563
541
return self.abspath(self.id2path(file_id))
605
def get_file_sha1(self, file_id, path=None, stat_value=None):
606
# FIXME: Shouldn't this be in Tree?
607
raise NotImplementedError(self.get_file_sha1)
609
583
@needs_tree_write_lock
610
584
def _gather_kinds(self, files, kinds):
611
585
"""See MutableTree._gather_kinds."""
777
751
@needs_tree_write_lock
778
752
def set_merge_modified(self, modified_hashes):
780
for file_id, hash in modified_hashes.iteritems():
781
yield _mod_rio.Stanza(file_id=file_id.decode('utf8'),
783
self._put_rio('merge-hashes', iter_stanzas(), MERGE_MODIFIED_HEADER_1)
753
"""Set the merge modified hashes."""
754
raise NotImplementedError(self.set_merge_modified)
785
756
def _sha_from_stat(self, path, stat_result):
786
757
"""Get a sha digest from the tree's stat cache.
795
def _put_rio(self, filename, stanzas, header):
796
self._must_be_locked()
797
my_file = _mod_rio.rio_file(stanzas, header)
798
self._transport.put_file(filename, my_file,
799
mode=self.bzrdir._get_file_mode())
801
766
@needs_write_lock # because merge pulls data into the branch.
802
767
def merge_from_branch(self, branch, to_revision=None, from_revision=None,
803
768
merge_type=None, force=False):
973
938
file and change the file_id. That is the normal mode. Second, it can
974
939
only change the file_id without touching any physical file.
976
rename_one uses the second mode if 'after == True' and 'to_rel' is not
977
versioned but present in the working tree.
941
rename_one uses the second mode if 'after == True' and 'to_rel' is
942
either not versioned or newly added, and present in the working tree.
979
944
rename_one uses the second mode if 'after == False' and 'from_rel' is
980
945
versioned but no longer in the working tree, and 'to_rel' is not
1043
1008
show_base=show_base)
1044
1009
basis_root_id = basis_tree.get_root_id()
1045
1010
new_root_id = new_basis_tree.get_root_id()
1046
if basis_root_id != new_root_id:
1011
if new_root_id is not None and basis_root_id != new_root_id:
1047
1012
self.set_root_id(new_root_id)
1049
1014
basis_tree.unlock()
1050
1015
# TODO - dedup parents list with things merged by pull ?
1051
1016
# reuse the revisiontree we merged against to set the new
1053
parent_trees = [(self.branch.last_revision(), new_basis_tree)]
1019
if self.branch.last_revision() != _mod_revision.NULL_REVISION:
1020
parent_trees.append(
1021
(self.branch.last_revision(), new_basis_tree))
1054
1022
# we have to pull the merge trees out again, because
1055
1023
# merge_inner has set the ids. - this corner is not yet
1056
1024
# layered well enough to prevent double handling.
1157
1124
mode = stat_value.st_mode
1158
1125
kind = osutils.file_kind_from_stat_mode(mode)
1159
if not supports_executable():
1126
if not self._supports_executable():
1160
1127
executable = entry is not None and entry.executable
1162
1129
executable = bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
1181
1148
return _mod_revision.ensure_null(self.branch.last_revision())
1183
1150
def is_locked(self):
1184
return self._control_files.is_locked()
1186
def _must_be_locked(self):
1187
if not self.is_locked():
1188
raise errors.ObjectNotLocked(self)
1151
"""Check if this tree is locked."""
1152
raise NotImplementedError(self.is_locked)
1190
1154
def lock_read(self):
1191
1155
"""Lock the tree for reading.
1195
1159
:return: A bzrlib.lock.LogicalLockResult.
1197
if not self.is_locked():
1199
self.branch.lock_read()
1201
self._control_files.lock_read()
1202
return LogicalLockResult(self.unlock)
1204
self.branch.unlock()
1161
raise NotImplementedError(self.lock_read)
1207
1163
def lock_tree_write(self):
1208
1164
"""See MutableTree.lock_tree_write, and WorkingTree.unlock.
1210
1166
:return: A bzrlib.lock.LogicalLockResult.
1212
if not self.is_locked():
1214
self.branch.lock_read()
1216
self._control_files.lock_write()
1217
return LogicalLockResult(self.unlock)
1219
self.branch.unlock()
1168
raise NotImplementedError(self.lock_tree_write)
1222
1170
def lock_write(self):
1223
1171
"""See MutableTree.lock_write, and WorkingTree.unlock.
1225
1173
:return: A bzrlib.lock.LogicalLockResult.
1227
if not self.is_locked():
1229
self.branch.lock_write()
1231
self._control_files.lock_write()
1232
return LogicalLockResult(self.unlock)
1234
self.branch.unlock()
1175
raise NotImplementedError(self.lock_write)
1237
1177
def get_physical_lock_status(self):
1238
return self._control_files.get_physical_lock_status()
1240
def _reset_data(self):
1241
"""Reset transient data that cannot be revalidated."""
1242
raise NotImplementedError(self._reset_data)
1178
raise NotImplementedError(self.get_physical_lock_status)
1244
1180
def set_last_revision(self, new_revision):
1245
1181
"""Change the last revision in the working tree."""
1385
1321
def revert(self, filenames=None, old_tree=None, backups=True,
1386
1322
pb=None, report_changes=False):
1387
1323
from bzrlib.conflicts import resolve
1390
symbol_versioning.warn('Using [] to revert all files is deprecated'
1391
' as of bzr 0.91. Please use None (the default) instead.',
1392
DeprecationWarning, stacklevel=2)
1393
1324
if old_tree is None:
1394
1325
basis_tree = self.basis_tree()
1395
1326
basis_tree.lock_read()
1544
1475
show_base=show_base)
1545
1476
if nb_conflicts:
1546
1477
self.add_parent_tree((old_tip, other_tree))
1547
note('Rerun update after fixing the conflicts.')
1478
note(gettext('Rerun update after fixing the conflicts.'))
1548
1479
return nb_conflicts
1550
1481
if last_rev != _mod_revision.ensure_null(revision):
1592
1523
last_rev = parent_trees[0][0]
1593
1524
return nb_conflicts
1595
def _write_hashcache_if_dirty(self):
1596
"""Write out the hashcache if it is dirty."""
1597
if self._hashcache.needs_write:
1599
self._hashcache.write()
1601
if e.errno not in (errno.EPERM, errno.EACCES):
1603
# TODO: jam 20061219 Should this be a warning? A single line
1604
# warning might be sufficient to let the user know what
1606
mutter('Could not write hashcache for %s\nError: %s',
1607
self._hashcache.cache_file_name(), e)
1609
1526
def set_conflicts(self, arg):
1610
1527
raise errors.UnsupportedOperation(self.set_conflicts, self)
1840
1757
:param branch: A branch to override probing for the branch.
1842
1759
super(InventoryWorkingTree, self).__init__(basedir=basedir,
1843
branch=branch, _control_files=_control_files, _internal=_internal,
1844
_format=_format, _bzrdir=_bzrdir)
1760
branch=branch, _transport=_control_files._transport,
1761
_internal=_internal, _format=_format, _bzrdir=_bzrdir)
1763
self._control_files = _control_files
1764
self._detect_case_handling()
1846
1766
if _inventory is None:
1847
1767
# This will be acquired on lock_read() or lock_write()
1867
1787
self._inventory = inv
1868
1788
self._inventory_is_modified = dirty
1790
def _detect_case_handling(self):
1791
wt_trans = self.bzrdir.get_workingtree_transport(None)
1793
wt_trans.stat(self._format.case_sensitive_filename)
1794
except errors.NoSuchFile:
1795
self.case_sensitive = True
1797
self.case_sensitive = False
1799
self._setup_directory_is_tree_reference()
1870
1801
def _serialize(self, inventory, out_file):
1871
1802
xml5.serializer_v5.write_inventory(self._inventory, out_file,
1874
1805
def _deserialize(selt, in_file):
1875
1806
return xml5.serializer_v5.read_inventory(in_file)
1808
def break_lock(self):
1809
"""Break a lock if one is present from another instance.
1811
Uses the ui factory to ask for confirmation if the lock may be from
1814
This will probe the repository for its lock as well.
1816
self._control_files.break_lock()
1817
self.branch.break_lock()
1819
def is_locked(self):
1820
return self._control_files.is_locked()
1822
def _must_be_locked(self):
1823
if not self.is_locked():
1824
raise errors.ObjectNotLocked(self)
1826
def lock_read(self):
1827
"""Lock the tree for reading.
1829
This also locks the branch, and can be unlocked via self.unlock().
1831
:return: A bzrlib.lock.LogicalLockResult.
1833
if not self.is_locked():
1835
self.branch.lock_read()
1837
self._control_files.lock_read()
1838
return LogicalLockResult(self.unlock)
1840
self.branch.unlock()
1843
def lock_tree_write(self):
1844
"""See MutableTree.lock_tree_write, and WorkingTree.unlock.
1846
:return: A bzrlib.lock.LogicalLockResult.
1848
if not self.is_locked():
1850
self.branch.lock_read()
1852
self._control_files.lock_write()
1853
return LogicalLockResult(self.unlock)
1855
self.branch.unlock()
1858
def lock_write(self):
1859
"""See MutableTree.lock_write, and WorkingTree.unlock.
1861
:return: A bzrlib.lock.LogicalLockResult.
1863
if not self.is_locked():
1865
self.branch.lock_write()
1867
self._control_files.lock_write()
1868
return LogicalLockResult(self.unlock)
1870
self.branch.unlock()
1873
def get_physical_lock_status(self):
1874
return self._control_files.get_physical_lock_status()
1877
1876
@needs_tree_write_lock
1878
1877
def _write_inventory(self, inv):
1879
1878
"""Write inventory as the current inventory."""
2178
2175
mode=self.bzrdir._get_file_mode())
2179
2176
self._inventory_is_modified = False
2182
def get_file_sha1(self, file_id, path=None, stat_value=None):
2184
path = self._inventory.id2path(file_id)
2185
return self._hashcache.get_sha1(path, stat_value)
2187
2178
def get_file_mtime(self, file_id, path=None):
2188
2179
"""See Tree.get_file_mtime."""
2190
2181
path = self.inventory.id2path(file_id)
2191
return os.lstat(self.abspath(path)).st_mtime
2183
return os.lstat(self.abspath(path)).st_mtime
2185
if e.errno == errno.ENOENT:
2186
raise errors.FileTimestampUnavailable(path)
2193
2189
def _is_executable_from_path_and_stat_from_basis(self, path, stat_result):
2194
2190
file_id = self.path2id(path)
2202
2198
mode = stat_result.st_mode
2203
2199
return bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
2205
if not supports_executable():
2206
def is_executable(self, file_id, path=None):
2201
def is_executable(self, file_id, path=None):
2202
if not self._supports_executable():
2207
2203
return self._inventory[file_id].executable
2209
_is_executable_from_path_and_stat = \
2210
_is_executable_from_path_and_stat_from_basis
2212
def is_executable(self, file_id, path=None):
2214
2206
path = self.id2path(file_id)
2215
2207
mode = os.lstat(self.abspath(path)).st_mode
2216
2208
return bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
2218
_is_executable_from_path_and_stat = \
2219
_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)
2214
return self._is_executable_from_path_and_stat_from_stat(path, stat_result)
2221
2216
@needs_tree_write_lock
2222
2217
def _add(self, files, ids, kinds):
2301
2296
for key, line in annotator.annotate_flat(this_key)]
2302
2297
return annotations
2299
def _put_rio(self, filename, stanzas, header):
2300
self._must_be_locked()
2301
my_file = _mod_rio.rio_file(stanzas, header)
2302
self._transport.put_file(filename, my_file,
2303
mode=self.bzrdir._get_file_mode())
2305
@needs_tree_write_lock
2306
def set_merge_modified(self, modified_hashes):
2308
for file_id, hash in modified_hashes.iteritems():
2309
yield _mod_rio.Stanza(file_id=file_id.decode('utf8'),
2311
self._put_rio('merge-hashes', iter_stanzas(), MERGE_MODIFIED_HEADER_1)
2304
2313
@needs_read_lock
2305
2314
def merge_modified(self):
2306
2315
"""Return a dictionary of files modified by a merge.
2326
2335
for s in _mod_rio.RioReader(hashfile):
2327
2336
# RioReader reads in Unicode, so convert file_ids back to utf8
2328
2337
file_id = osutils.safe_file_id(s.get("file_id"), warn=False)
2329
if file_id not in self.inventory:
2338
if not self.inventory.has_id(file_id):
2331
2340
text_hash = s.get("hash")
2332
2341
if text_hash == self.get_file_sha1(file_id):
2573
2582
inventory. The second mode only updates the inventory without
2574
2583
touching the file on the filesystem.
2576
move uses the second mode if 'after == True' and the target is not
2577
versioned but present in the working tree.
2585
move uses the second mode if 'after == True' and the target is
2586
either not versioned or newly added, and present in the working tree.
2579
2588
move uses the second mode if 'after == False' and the source is
2580
2589
versioned but no longer in the working tree, and the target is not
2728
2737
class _RenameEntry(object):
2729
2738
def __init__(self, from_rel, from_id, from_tail, from_parent_id,
2730
to_rel, to_tail, to_parent_id, only_change_inv=False):
2739
to_rel, to_tail, to_parent_id, only_change_inv=False,
2731
2741
self.from_rel = from_rel
2732
2742
self.from_id = from_id
2733
2743
self.from_tail = from_tail
2735
2745
self.to_rel = to_rel
2736
2746
self.to_tail = to_tail
2737
2747
self.to_parent_id = to_parent_id
2748
self.change_id = change_id
2738
2749
self.only_change_inv = only_change_inv
2740
2751
def _determine_mv_mode(self, rename_entries, after=False):
2752
2763
to_rel = rename_entry.to_rel
2753
2764
to_id = inv.path2id(to_rel)
2754
2765
only_change_inv = False
2756
2768
# check the inventory for source and destination
2757
2769
if from_id is None:
2758
2770
raise errors.BzrMoveFailedError(from_rel,to_rel,
2759
2771
errors.NotVersionedError(path=from_rel))
2760
2772
if to_id is not None:
2761
raise errors.BzrMoveFailedError(from_rel,to_rel,
2762
errors.AlreadyVersionedError(path=to_rel))
2774
# allow it with --after but only if dest is newly added
2776
basis = self.basis_tree()
2779
if not basis.has_id(to_id):
2780
rename_entry.change_id = True
2785
raise errors.BzrMoveFailedError(from_rel,to_rel,
2786
errors.AlreadyVersionedError(path=to_rel))
2764
2788
# try to determine the mode for rename (only change inv or change
2765
2789
# inv and file system)
2781
2805
# something is wrong, so lets determine what exactly
2782
2806
if not self.has_filename(from_rel) and \
2783
2807
not self.has_filename(to_rel):
2784
raise errors.BzrRenameFailedError(from_rel,to_rel,
2785
errors.PathsDoNotExist(paths=(str(from_rel),
2808
raise errors.BzrRenameFailedError(from_rel, to_rel,
2809
errors.PathsDoNotExist(paths=(from_rel, to_rel)))
2788
2811
raise errors.RenameFailedFilesExist(from_rel, to_rel)
2789
2812
rename_entry.only_change_inv = only_change_inv
2836
2859
except OSError, e:
2837
2860
raise errors.BzrMoveFailedError(entry.from_rel,
2838
2861
entry.to_rel, e[1])
2863
to_id = inv.path2id(entry.to_rel)
2864
inv.remove_recursive_id(to_id)
2839
2865
inv.rename(entry.from_id, entry.to_parent_id, entry.to_tail)
2841
2867
@needs_tree_write_lock
2849
2875
:raises: NoSuchId if any fileid is not currently versioned.
2851
2877
for file_id in file_ids:
2852
if file_id not in self._inventory:
2878
if not self._inventory.has_id(file_id):
2853
2879
raise errors.NoSuchId(self, file_id)
2854
2880
for file_id in file_ids:
2855
2881
if self._inventory.has_id(file_id):
2951
2977
if dir[2] == _directory:
2952
2978
pending.append(dir)
2981
def update_feature_flags(self, updated_flags):
2982
"""Update the feature flags for this branch.
2984
:param updated_flags: Dictionary mapping feature names to necessities
2985
A necessity can be None to indicate the feature should be removed
2987
self._format._update_feature_flags(updated_flags)
2988
self.control_transport.put_bytes('format', self._format.as_string())
2955
2991
class WorkingTreeFormatRegistry(controldir.ControlComponentFormatRegistry):
2956
2992
"""Registry for working tree formats."""
3010
3046
missing_parent_conflicts = False
3011
3047
"""If this format supports missing parent conflicts."""
3014
def find_format_string(klass, a_bzrdir):
3015
"""Return format name for the working tree object in a_bzrdir."""
3017
transport = a_bzrdir.get_workingtree_transport(None)
3018
return transport.get_bytes("format")
3019
except errors.NoSuchFile:
3020
raise errors.NoWorkingTree(base=transport.base)
3023
def find_format(klass, a_bzrdir):
3024
"""Return the format for the working tree object in a_bzrdir."""
3026
format_string = klass.find_format_string(a_bzrdir)
3027
return format_registry.get(format_string)
3029
raise errors.UnknownFormatError(format=format_string,
3030
kind="working tree")
3032
def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
3049
supports_versioned_directories = None
3051
def initialize(self, controldir, revision_id=None, from_branch=None,
3033
3052
accelerator_tree=None, hardlink=False):
3034
"""Initialize a new working tree in a_bzrdir.
3053
"""Initialize a new working tree in controldir.
3036
:param a_bzrdir: BzrDir to initialize the working tree in.
3055
:param controldir: ControlDir to initialize the working tree in.
3037
3056
:param revision_id: allows creating a working tree at a different
3038
3057
revision than the branch is at.
3039
3058
:param from_branch: Branch to checkout
3059
3078
"""Return the current default format."""
3060
3079
return format_registry.get_default()
3062
def get_format_string(self):
3063
"""Return the ASCII format string that identifies this format."""
3064
raise NotImplementedError(self.get_format_string)
3066
3081
def get_format_description(self):
3067
3082
"""Return the short description for this format."""
3068
3083
raise NotImplementedError(self.get_format_description)
3120
3135
def unregister_format(klass, format):
3121
3136
format_registry.remove(format)
3138
def get_controldir_for_branch(self):
3139
"""Get the control directory format for creating branches.
3141
This is to support testing of working tree formats that can not exist
3142
in the same control directory as a branch.
3144
return self._matchingbzrdir
3147
class WorkingTreeFormatMetaDir(bzrdir.BzrFormat, WorkingTreeFormat):
3148
"""Base class for working trees that live in bzr meta directories."""
3151
WorkingTreeFormat.__init__(self)
3152
bzrdir.BzrFormat.__init__(self)
3155
def find_format_string(klass, controldir):
3156
"""Return format name for the working tree object in controldir."""
3158
transport = controldir.get_workingtree_transport(None)
3159
return transport.get_bytes("format")
3160
except errors.NoSuchFile:
3161
raise errors.NoWorkingTree(base=transport.base)
3164
def find_format(klass, controldir):
3165
"""Return the format for the working tree object in controldir."""
3166
format_string = klass.find_format_string(controldir)
3167
return klass._find_format(format_registry, 'working tree',
3170
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
3172
WorkingTreeFormat.check_support_status(self,
3173
allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
3175
bzrdir.BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
3176
recommend_upgrade=recommend_upgrade, basedir=basedir)
3124
3179
format_registry.register_lazy("Bazaar Working Tree Format 4 (bzr 0.15)\n",
3125
3180
"bzrlib.workingtree_4", "WorkingTreeFormat4")