193
199
self._branch = self.bzrdir.open_branch()
194
200
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()
201
self._transport = _transport
218
202
self._rules_searcher = None
219
203
self.views = self._make_views()
1195
1169
: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()
1171
raise NotImplementedError(self.lock_read)
1207
1173
def lock_tree_write(self):
1208
1174
"""See MutableTree.lock_tree_write, and WorkingTree.unlock.
1210
1176
: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()
1178
raise NotImplementedError(self.lock_tree_write)
1222
1180
def lock_write(self):
1223
1181
"""See MutableTree.lock_write, and WorkingTree.unlock.
1225
1183
: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()
1185
raise NotImplementedError(self.lock_write)
1237
1187
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)
1188
raise NotImplementedError(self.get_physical_lock_status)
1244
1190
def set_last_revision(self, new_revision):
1245
1191
"""Change the last revision in the working tree."""
1416
1357
basis_tree.unlock()
1417
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()
1419
1388
def revision_tree(self, revision_id):
1420
1389
"""See Tree.revision_tree.
1874
1843
def _deserialize(selt, in_file):
1875
1844
return xml5.serializer_v5.read_inventory(in_file)
1846
def break_lock(self):
1847
"""Break a lock if one is present from another instance.
1849
Uses the ui factory to ask for confirmation if the lock may be from
1852
This will probe the repository for its lock as well.
1854
self._control_files.break_lock()
1855
self.branch.break_lock()
1857
def is_locked(self):
1858
return self._control_files.is_locked()
1860
def _must_be_locked(self):
1861
if not self.is_locked():
1862
raise errors.ObjectNotLocked(self)
1864
def lock_read(self):
1865
"""Lock the tree for reading.
1867
This also locks the branch, and can be unlocked via self.unlock().
1869
:return: A bzrlib.lock.LogicalLockResult.
1871
if not self.is_locked():
1873
self.branch.lock_read()
1875
self._control_files.lock_read()
1876
return LogicalLockResult(self.unlock)
1878
self.branch.unlock()
1881
def lock_tree_write(self):
1882
"""See MutableTree.lock_tree_write, and WorkingTree.unlock.
1884
:return: A bzrlib.lock.LogicalLockResult.
1886
if not self.is_locked():
1888
self.branch.lock_read()
1890
self._control_files.lock_write()
1891
return LogicalLockResult(self.unlock)
1893
self.branch.unlock()
1896
def lock_write(self):
1897
"""See MutableTree.lock_write, and WorkingTree.unlock.
1899
:return: A bzrlib.lock.LogicalLockResult.
1901
if not self.is_locked():
1903
self.branch.lock_write()
1905
self._control_files.lock_write()
1906
return LogicalLockResult(self.unlock)
1908
self.branch.unlock()
1911
def get_physical_lock_status(self):
1912
return self._control_files.get_physical_lock_status()
1877
1914
@needs_tree_write_lock
1878
1915
def _write_inventory(self, inv):
1879
1916
"""Write inventory as the current inventory."""
2079
2112
def has_id(self, file_id):
2080
2113
# files that have been deleted are excluded
2081
inv = self.inventory
2082
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):
2084
path = inv.id2path(file_id)
2117
path = inv.id2path(inv_file_id)
2085
2118
return osutils.lexists(self.abspath(path))
2087
2120
def has_or_had_id(self, file_id):
2088
if file_id == self.inventory.root.file_id:
2121
if file_id == self.get_root_id():
2090
return self.inventory.has_id(file_id)
2092
__contains__ = has_id
2094
@symbol_versioning.deprecated_method(symbol_versioning.deprecated_in((2, 4, 0)))
2123
inv, inv_file_id = self._unpack_file_id(file_id)
2124
return inv.has_id(inv_file_id)
2126
def all_file_ids(self):
2096
2127
"""Iterate through file_ids for this tree.
2098
2129
file_ids are in a WorkingTree if they are in the working inventory
2099
2130
and the working file exists.
2101
inv = self._inventory
2102
for path, ie in inv.iter_entries():
2103
if osutils.lexists(self.abspath(path)):
2133
for path, ie in self.iter_entries_by_dir():
2106
2137
@needs_tree_write_lock
2107
2138
def set_last_revision(self, new_revision):
2178
2209
mode=self.bzrdir._get_file_mode())
2179
2210
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
2212
def get_file_mtime(self, file_id, path=None):
2188
2213
"""See Tree.get_file_mtime."""
2190
path = self.inventory.id2path(file_id)
2191
return os.lstat(self.abspath(path)).st_mtime
2215
path = self.id2path(file_id)
2217
return os.lstat(self.abspath(path)).st_mtime
2219
if e.errno == errno.ENOENT:
2220
raise errors.FileTimestampUnavailable(path)
2193
2223
def _is_executable_from_path_and_stat_from_basis(self, path, stat_result):
2194
file_id = self.path2id(path)
2224
inv, file_id = self._path2inv_file_id(path)
2195
2225
if file_id is None:
2196
2226
# For unversioned files on win32, we just assume they are not
2199
return self._inventory[file_id].executable
2229
return inv[file_id].executable
2201
2231
def _is_executable_from_path_and_stat_from_stat(self, path, stat_result):
2202
2232
mode = stat_result.st_mode
2203
2233
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):
2207
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):
2235
def is_executable(self, file_id, path=None):
2236
if not self._supports_executable():
2237
inv, inv_file_id = self._unpack_file_id(file_id)
2238
return inv[inv_file_id].executable
2214
2241
path = self.id2path(file_id)
2215
2242
mode = os.lstat(self.abspath(path)).st_mode
2216
2243
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
2245
def _is_executable_from_path_and_stat(self, path, stat_result):
2246
if not self._supports_executable():
2247
return self._is_executable_from_path_and_stat_from_basis(path, stat_result)
2249
return self._is_executable_from_path_and_stat_from_stat(path, stat_result)
2221
2251
@needs_tree_write_lock
2222
2252
def _add(self, files, ids, kinds):
2301
2334
for key, line in annotator.annotate_flat(this_key)]
2302
2335
return annotations
2337
def _put_rio(self, filename, stanzas, header):
2338
self._must_be_locked()
2339
my_file = _mod_rio.rio_file(stanzas, header)
2340
self._transport.put_file(filename, my_file,
2341
mode=self.bzrdir._get_file_mode())
2343
@needs_tree_write_lock
2344
def set_merge_modified(self, modified_hashes):
2346
for file_id, hash in modified_hashes.iteritems():
2347
yield _mod_rio.Stanza(file_id=file_id.decode('utf8'),
2349
self._put_rio('merge-hashes', iter_stanzas(), MERGE_MODIFIED_HEADER_1)
2304
2351
@needs_read_lock
2305
2352
def merge_modified(self):
2306
2353
"""Return a dictionary of files modified by a merge.
2362
2409
other_tree.lock_tree_write()
2364
2411
new_parents = other_tree.get_parent_ids()
2365
other_root = other_tree.inventory.root
2412
other_root = other_tree.root_inventory.root
2366
2413
other_root.parent_id = new_root_parent
2367
2414
other_root.name = osutils.basename(other_tree_path)
2368
self.inventory.add(other_root)
2369
add_children(self.inventory, other_root)
2370
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)
2371
2418
# normally we don't want to fetch whole repositories, but i think
2372
2419
# here we really do want to consolidate the whole thing.
2373
2420
for parent_id in other_tree.get_parent_ids():
2689
2737
raise errors.BzrRenameFailedError(from_rel,to_rel,
2690
2738
errors.NotVersionedError(path=from_rel))
2691
2739
# put entry back in the inventory so we can rename it
2692
from_entry = basis_tree.inventory[from_id].copy()
2740
from_entry = basis_tree.root_inventory[from_id].copy()
2741
from_inv.add(from_entry)
2695
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]
2696
2745
from_parent_id = from_entry.parent_id
2697
2746
to_dir, to_tail = os.path.split(to_rel)
2698
to_dir_id = inv.path2id(to_dir)
2747
to_inv, to_dir_id = self._path2inv_file_id(to_dir)
2699
2748
rename_entry = InventoryWorkingTree._RenameEntry(from_rel=from_rel,
2700
2749
from_id=from_id,
2701
2750
from_tail=from_tail,
2723
2772
from_id, from_rel, to_rel, to_dir, to_dir_id)
2725
2774
self._move(rename_entries)
2726
self._write_inventory(inv)
2775
self._write_inventory(to_inv)
2728
2777
class _RenameEntry(object):
2729
2778
def __init__(self, from_rel, from_id, from_tail, from_parent_id,
2730
to_rel, to_tail, to_parent_id, only_change_inv=False):
2779
to_rel, to_tail, to_parent_id, only_change_inv=False,
2731
2781
self.from_rel = from_rel
2732
2782
self.from_id = from_id
2733
2783
self.from_tail = from_tail
2752
2804
to_rel = rename_entry.to_rel
2753
2805
to_id = inv.path2id(to_rel)
2754
2806
only_change_inv = False
2756
2809
# check the inventory for source and destination
2757
2810
if from_id is None:
2758
2811
raise errors.BzrMoveFailedError(from_rel,to_rel,
2759
2812
errors.NotVersionedError(path=from_rel))
2760
2813
if to_id is not None:
2761
raise errors.BzrMoveFailedError(from_rel,to_rel,
2762
errors.AlreadyVersionedError(path=to_rel))
2815
# allow it with --after but only if dest is newly added
2817
basis = self.basis_tree()
2820
if not basis.has_id(to_id):
2821
rename_entry.change_id = True
2826
raise errors.BzrMoveFailedError(from_rel,to_rel,
2827
errors.AlreadyVersionedError(path=to_rel))
2764
2829
# try to determine the mode for rename (only change inv or change
2765
2830
# inv and file system)
3010
3087
missing_parent_conflicts = False
3011
3088
"""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,
3090
supports_versioned_directories = None
3092
def initialize(self, controldir, revision_id=None, from_branch=None,
3033
3093
accelerator_tree=None, hardlink=False):
3034
"""Initialize a new working tree in a_bzrdir.
3094
"""Initialize a new working tree in controldir.
3036
:param a_bzrdir: BzrDir to initialize the working tree in.
3096
:param controldir: ControlDir to initialize the working tree in.
3037
3097
:param revision_id: allows creating a working tree at a different
3038
3098
revision than the branch is at.
3039
3099
:param from_branch: Branch to checkout
3084
3133
"""True if this format supports stored views."""
3088
@symbol_versioning.deprecated_method(
3089
symbol_versioning.deprecated_in((2, 4, 0)))
3090
def register_format(klass, format):
3091
format_registry.register(format)
3094
@symbol_versioning.deprecated_method(
3095
symbol_versioning.deprecated_in((2, 4, 0)))
3096
def register_extra_format(klass, format):
3097
format_registry.register_extra(format)
3100
@symbol_versioning.deprecated_method(
3101
symbol_versioning.deprecated_in((2, 4, 0)))
3102
def unregister_extra_format(klass, format):
3103
format_registry.unregister_extra(format)
3106
@symbol_versioning.deprecated_method(
3107
symbol_versioning.deprecated_in((2, 4, 0)))
3108
def get_formats(klass):
3109
return format_registry._get_all()
3112
@symbol_versioning.deprecated_method(
3113
symbol_versioning.deprecated_in((2, 4, 0)))
3114
def set_default_format(klass, format):
3115
format_registry.set_default(format)
3118
@symbol_versioning.deprecated_method(
3119
symbol_versioning.deprecated_in((2, 4, 0)))
3120
def unregister_format(klass, format):
3121
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)
3176
def get_controldir_for_branch(self):
3177
"""Get the control directory format for creating branches.
3179
This is to support testing of working tree formats that can not exist
3180
in the same control directory as a branch.
3182
return self._matchingbzrdir
3185
class WorkingTreeFormatMetaDir(bzrdir.BzrFormat, WorkingTreeFormat):
3186
"""Base class for working trees that live in bzr meta directories."""
3189
WorkingTreeFormat.__init__(self)
3190
bzrdir.BzrFormat.__init__(self)
3193
def find_format_string(klass, controldir):
3194
"""Return format name for the working tree object in controldir."""
3196
transport = controldir.get_workingtree_transport(None)
3197
return transport.get_bytes("format")
3198
except errors.NoSuchFile:
3199
raise errors.NoWorkingTree(base=transport.base)
3202
def find_format(klass, controldir):
3203
"""Return the format for the working tree object in controldir."""
3204
format_string = klass.find_format_string(controldir)
3205
return klass._find_format(format_registry, 'working tree',
3208
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
3210
WorkingTreeFormat.check_support_status(self,
3211
allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
3213
bzrdir.BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
3214
recommend_upgrade=recommend_upgrade, basedir=basedir)
3124
3217
format_registry.register_lazy("Bazaar Working Tree Format 4 (bzr 0.15)\n",