261
262
def supports_views(self):
262
263
return self.views.supports_views()
265
def get_config_stack(self):
266
"""Retrieve the config stack for this tree.
268
:return: A ``bzrlib.config.Stack``
270
# For the moment, just provide the branch config stack.
271
return self.branch.get_config_stack()
265
274
def open(path=None, _unsupported=False):
266
275
"""Open an existing working tree at path.
1347
1357
basis_tree.unlock()
1348
1358
return conflicts
1361
def store_uncommitted(self):
1362
"""Store uncommitted changes from the tree in the branch."""
1363
target_tree = self.basis_tree()
1364
shelf_creator = shelf.ShelfCreator(self, target_tree)
1366
if not shelf_creator.shelve_all():
1368
self.branch.store_uncommitted(shelf_creator)
1369
shelf_creator.transform()
1371
shelf_creator.finalize()
1372
note('Uncommitted changes stored in branch "%s".', self.branch.nick)
1375
def restore_uncommitted(self):
1376
"""Restore uncommitted changes from the branch into the tree."""
1377
unshelver = self.branch.get_unshelver(self)
1378
if unshelver is None:
1381
merger = unshelver.make_merger()
1382
merger.ignore_zero = True
1384
self.branch.store_uncommitted(None)
1386
unshelver.finalize()
1350
1388
def revision_tree(self, revision_id):
1351
1389
"""See Tree.revision_tree.
2078
2112
def has_id(self, file_id):
2079
2113
# files that have been deleted are excluded
2080
inv = self.inventory
2081
if not inv.has_id(file_id):
2114
inv, inv_file_id = self._unpack_file_id(file_id)
2115
if not inv.has_id(inv_file_id):
2083
path = inv.id2path(file_id)
2117
path = inv.id2path(inv_file_id)
2084
2118
return osutils.lexists(self.abspath(path))
2086
2120
def has_or_had_id(self, file_id):
2087
if file_id == self.inventory.root.file_id:
2121
if file_id == self.get_root_id():
2089
return self.inventory.has_id(file_id)
2123
inv, inv_file_id = self._unpack_file_id(file_id)
2124
return inv.has_id(inv_file_id)
2091
@symbol_versioning.deprecated_method(symbol_versioning.deprecated_in((2, 4, 0)))
2126
def all_file_ids(self):
2093
2127
"""Iterate through file_ids for this tree.
2095
2129
file_ids are in a WorkingTree if they are in the working inventory
2096
2130
and the working file exists.
2098
inv = self._inventory
2099
for path, ie in inv.iter_entries():
2100
if osutils.lexists(self.abspath(path)):
2133
for path, ie in self.iter_entries_by_dir():
2103
2137
@needs_tree_write_lock
2104
2138
def set_last_revision(self, new_revision):
2189
2223
def _is_executable_from_path_and_stat_from_basis(self, path, stat_result):
2190
file_id = self.path2id(path)
2224
inv, file_id = self._path2inv_file_id(path)
2191
2225
if file_id is None:
2192
2226
# For unversioned files on win32, we just assume they are not
2195
return self._inventory[file_id].executable
2229
return inv[file_id].executable
2197
2231
def _is_executable_from_path_and_stat_from_stat(self, path, stat_result):
2198
2232
mode = stat_result.st_mode
2267
2303
parent_tree = self.branch.repository.revision_tree(parent_id)
2268
2304
parent_tree.lock_read()
2270
if not parent_tree.has_id(file_id):
2307
kind = parent_tree.kind(file_id)
2308
except errors.NoSuchId:
2272
ie = parent_tree.inventory[file_id]
2273
if ie.kind != 'file':
2274
2311
# Note: this is slightly unnecessary, because symlinks and
2275
2312
# directories have a "text" which is the empty text, and we
2276
2313
# know that won't mess up annotations. But it seems cleaner
2278
parent_text_key = (file_id, ie.revision)
2316
file_id, parent_tree.get_file_revision(file_id))
2279
2317
if parent_text_key not in maybe_file_parent_keys:
2280
2318
maybe_file_parent_keys.append(parent_text_key)
2371
2409
other_tree.lock_tree_write()
2373
2411
new_parents = other_tree.get_parent_ids()
2374
other_root = other_tree.inventory.root
2412
other_root = other_tree.root_inventory.root
2375
2413
other_root.parent_id = new_root_parent
2376
2414
other_root.name = osutils.basename(other_tree_path)
2377
self.inventory.add(other_root)
2378
add_children(self.inventory, other_root)
2379
self._write_inventory(self.inventory)
2415
self.root_inventory.add(other_root)
2416
add_children(self.root_inventory, other_root)
2417
self._write_inventory(self.root_inventory)
2380
2418
# normally we don't want to fetch whole repositories, but i think
2381
2419
# here we really do want to consolidate the whole thing.
2382
2420
for parent_id in other_tree.get_parent_ids():
2451
2490
if not self.is_locked():
2452
2491
raise errors.ObjectNotLocked(self)
2454
inv = self.inventory
2455
2493
if from_dir is None and include_root is True:
2456
yield ('', 'V', 'directory', inv.root.file_id, inv.root)
2494
yield ('', 'V', 'directory', self.get_root_id(), self.root_inventory.root)
2457
2495
# Convert these into local objects to save lookup times
2458
2496
pathjoin = osutils.pathjoin
2459
2497
file_kind = self._kind
2467
2505
# directory file_id, relative path, absolute path, reverse sorted children
2468
2506
if from_dir is not None:
2469
from_dir_id = inv.path2id(from_dir)
2507
inv, from_dir_id = self._path2inv_file_id(from_dir)
2470
2508
if from_dir_id is None:
2471
2509
# Directory not versioned
2473
2511
from_dir_abspath = pathjoin(self.basedir, from_dir)
2513
inv = self.root_inventory
2475
2514
from_dir_id = inv.root.file_id
2476
2515
from_dir_abspath = self.basedir
2477
2516
children = os.listdir(from_dir_abspath)
2614
2654
if not self.has_filename(to_dir):
2615
2655
raise errors.BzrMoveFailedError('',to_dir,
2616
2656
errors.NotInWorkingDirectory(to_dir))
2617
to_dir_id = inv.path2id(to_dir)
2657
to_inv, to_dir_id = self._path2inv_file_id(to_dir)
2618
2658
if to_dir_id is None:
2619
2659
raise errors.BzrMoveFailedError('',to_dir,
2620
2660
errors.NotVersionedError(path=to_dir))
2622
to_dir_ie = inv[to_dir_id]
2662
to_dir_ie = to_inv[to_dir_id]
2623
2663
if to_dir_ie.kind != 'directory':
2624
2664
raise errors.BzrMoveFailedError('',to_dir,
2625
2665
errors.NotADirectory(to_abs))
2627
2667
# create rename entries and tuples
2628
2668
for from_rel in from_paths:
2629
2669
from_tail = splitpath(from_rel)[-1]
2630
from_id = inv.path2id(from_rel)
2670
from_inv, from_id = self._path2inv_file_id(from_rel)
2631
2671
if from_id is None:
2632
2672
raise errors.BzrMoveFailedError(from_rel,to_dir,
2633
2673
errors.NotVersionedError(path=from_rel))
2635
from_entry = inv[from_id]
2675
from_entry = from_inv[from_id]
2636
2676
from_parent_id = from_entry.parent_id
2637
2677
to_rel = pathjoin(to_dir, from_tail)
2638
2678
rename_entry = InventoryWorkingTree._RenameEntry(
2697
2737
raise errors.BzrRenameFailedError(from_rel,to_rel,
2698
2738
errors.NotVersionedError(path=from_rel))
2699
2739
# put entry back in the inventory so we can rename it
2700
from_entry = basis_tree.inventory[from_id].copy()
2740
from_entry = basis_tree.root_inventory[from_id].copy()
2741
from_inv.add(from_entry)
2703
from_entry = inv[from_id]
2743
from_inv, from_inv_id = self._unpack_file_id(from_id)
2744
from_entry = from_inv[from_inv_id]
2704
2745
from_parent_id = from_entry.parent_id
2705
2746
to_dir, to_tail = os.path.split(to_rel)
2706
to_dir_id = inv.path2id(to_dir)
2747
to_inv, to_dir_id = self._path2inv_file_id(to_dir)
2707
2748
rename_entry = InventoryWorkingTree._RenameEntry(from_rel=from_rel,
2708
2749
from_id=from_id,
2709
2750
from_tail=from_tail,
2731
2772
from_id, from_rel, to_rel, to_dir, to_dir_id)
2733
2774
self._move(rename_entries)
2734
self._write_inventory(inv)
2775
self._write_inventory(to_inv)
2736
2777
class _RenameEntry(object):
2737
2778
def __init__(self, from_rel, from_id, from_tail, from_parent_id,
3070
3112
def __ne__(self, other):
3071
3113
return not (self == other)
3074
@symbol_versioning.deprecated_method(
3075
symbol_versioning.deprecated_in((2, 4, 0)))
3076
def get_default_format(klass):
3077
"""Return the current default format."""
3078
return format_registry.get_default()
3080
3115
def get_format_description(self):
3081
3116
"""Return the short description for this format."""
3082
3117
raise NotImplementedError(self.get_format_description)
3098
3133
"""True if this format supports stored views."""
3102
@symbol_versioning.deprecated_method(
3103
symbol_versioning.deprecated_in((2, 4, 0)))
3104
def register_format(klass, format):
3105
format_registry.register(format)
3108
@symbol_versioning.deprecated_method(
3109
symbol_versioning.deprecated_in((2, 4, 0)))
3110
def register_extra_format(klass, format):
3111
format_registry.register_extra(format)
3114
@symbol_versioning.deprecated_method(
3115
symbol_versioning.deprecated_in((2, 4, 0)))
3116
def unregister_extra_format(klass, format):
3117
format_registry.unregister_extra(format)
3120
@symbol_versioning.deprecated_method(
3121
symbol_versioning.deprecated_in((2, 4, 0)))
3122
def get_formats(klass):
3123
return format_registry._get_all()
3126
@symbol_versioning.deprecated_method(
3127
symbol_versioning.deprecated_in((2, 4, 0)))
3128
def set_default_format(klass, format):
3129
format_registry.set_default(format)
3132
@symbol_versioning.deprecated_method(
3133
symbol_versioning.deprecated_in((2, 4, 0)))
3134
def unregister_format(klass, format):
3135
format_registry.remove(format)
3136
def get_controldir_for_branch(self):
3137
"""Get the control directory format for creating branches.
3139
This is to support testing of working tree formats that can not exist
3140
in the same control directory as a branch.
3142
return self._matchingbzrdir
3145
class WorkingTreeFormatMetaDir(bzrdir.BzrFormat, WorkingTreeFormat):
3146
"""Base class for working trees that live in bzr meta directories."""
3149
WorkingTreeFormat.__init__(self)
3150
bzrdir.BzrFormat.__init__(self)
3153
def find_format_string(klass, controldir):
3154
"""Return format name for the working tree object in controldir."""
3156
transport = controldir.get_workingtree_transport(None)
3157
return transport.get_bytes("format")
3158
except errors.NoSuchFile:
3159
raise errors.NoWorkingTree(base=transport.base)
3162
def find_format(klass, controldir):
3163
"""Return the format for the working tree object in controldir."""
3164
format_string = klass.find_format_string(controldir)
3165
return klass._find_format(format_registry, 'working tree',
3168
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
3170
WorkingTreeFormat.check_support_status(self,
3171
allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
3173
bzrdir.BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
3174
recommend_upgrade=recommend_upgrade, basedir=basedir)
3137
3176
def get_controldir_for_branch(self):
3138
3177
"""Get the control directory format for creating branches.