73
# Explicitly import bzrlib.bzrdir so that the BzrProber
74
# is guaranteed to be registered.
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
173
177
def __init__(self, basedir='.',
174
178
branch=DEPRECATED_PARAMETER,
179
183
"""Construct a WorkingTree instance. This is not a public API.
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
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()
199
self._transport = _transport
218
200
self._rules_searcher = None
219
201
self.views = self._make_views()
239
221
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
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.
231
def has_versioned_directories(self):
232
"""See `Tree.has_versioned_directories`."""
233
return self._format.supports_versioned_directories
235
def _supports_executable(self):
236
if sys.platform == 'win32':
238
# FIXME: Ideally this should check the file system
260
241
def break_lock(self):
261
242
"""Break a lock if one is present from another instance.
266
247
This will probe the repository for its lock as well.
268
self._control_files.break_lock()
269
self.branch.break_lock()
249
raise NotImplementedError(self.break_lock)
271
251
def requires_rich_root(self):
272
252
return self._format.requires_rich_root
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
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]
522
502
raise NotImplementedError(self.get_root_id)
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.
528
508
Specifically modified files are kept as modified, but
529
509
ignored and unknown files are discarded.
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()
534
514
If not None, the cloned tree will have its last revision set to
536
516
and this one merged in.
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)
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:
536
new_parents = [revision_id]
537
tree.set_parent_ids(new_parents)
555
539
def id2abspath(self, file_id):
556
540
return self.abspath(self.id2path(file_id))
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)
602
582
@needs_tree_write_lock
603
583
def _gather_kinds(self, files, kinds):
604
584
"""See MutableTree._gather_kinds."""
770
750
@needs_tree_write_lock
771
751
def set_merge_modified(self, modified_hashes):
773
for file_id, hash in modified_hashes.iteritems():
774
yield _mod_rio.Stanza(file_id=file_id.decode('utf8'),
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)
778
755
def _sha_from_stat(self, path, stat_result):
779
756
"""Get a sha digest from the tree's stat cache.
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())
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)
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
1046
parent_trees = [(self.branch.last_revision(), new_basis_tree)]
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.
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
1155
1128
executable = bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
1174
1147
return _mod_revision.ensure_null(self.branch.last_revision())
1176
1149
def is_locked(self):
1177
return self._control_files.is_locked()
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)
1183
1153
def lock_read(self):
1184
1154
"""Lock the tree for reading.
1188
1158
:return: A bzrlib.lock.LogicalLockResult.
1190
if not self.is_locked():
1192
self.branch.lock_read()
1194
self._control_files.lock_read()
1195
return LogicalLockResult(self.unlock)
1197
self.branch.unlock()
1160
raise NotImplementedError(self.lock_read)
1200
1162
def lock_tree_write(self):
1201
1163
"""See MutableTree.lock_tree_write, and WorkingTree.unlock.
1203
1165
:return: A bzrlib.lock.LogicalLockResult.
1205
if not self.is_locked():
1207
self.branch.lock_read()
1209
self._control_files.lock_write()
1210
return LogicalLockResult(self.unlock)
1212
self.branch.unlock()
1167
raise NotImplementedError(self.lock_tree_write)
1215
1169
def lock_write(self):
1216
1170
"""See MutableTree.lock_write, and WorkingTree.unlock.
1218
1172
:return: A bzrlib.lock.LogicalLockResult.
1220
if not self.is_locked():
1222
self.branch.lock_write()
1224
self._control_files.lock_write()
1225
return LogicalLockResult(self.unlock)
1227
self.branch.unlock()
1174
raise NotImplementedError(self.lock_write)
1230
1176
def get_physical_lock_status(self):
1231
return self._control_files.get_physical_lock_status()
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)
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
1538
1480
if last_rev != _mod_revision.ensure_null(revision):
1580
1522
last_rev = parent_trees[0][0]
1581
1523
return nb_conflicts
1583
def _write_hashcache_if_dirty(self):
1584
"""Write out the hashcache if it is dirty."""
1585
if self._hashcache.needs_write:
1587
self._hashcache.write()
1589
if e.errno not in (errno.EPERM, errno.EACCES):
1591
# TODO: jam 20061219 Should this be a warning? A single line
1592
# warning might be sufficient to let the user know what
1594
mutter('Could not write hashcache for %s\nError: %s',
1595
self._hashcache.cache_file_name(), e)
1597
1525
def set_conflicts(self, arg):
1598
1526
raise errors.UnsupportedOperation(self.set_conflicts, self)
1828
1756
:param branch: A branch to override probing for the branch.
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)
1762
self._control_files = _control_files
1763
self._detect_case_handling()
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
1789
def _detect_case_handling(self):
1790
wt_trans = self.bzrdir.get_workingtree_transport(None)
1792
wt_trans.stat(self._format.case_sensitive_filename)
1793
except errors.NoSuchFile:
1794
self.case_sensitive = True
1796
self.case_sensitive = False
1798
self._setup_directory_is_tree_reference()
1858
1800
def _serialize(self, inventory, out_file):
1859
1801
xml5.serializer_v5.write_inventory(self._inventory, out_file,
1862
1804
def _deserialize(selt, in_file):
1863
1805
return xml5.serializer_v5.read_inventory(in_file)
1807
def break_lock(self):
1808
"""Break a lock if one is present from another instance.
1810
Uses the ui factory to ask for confirmation if the lock may be from
1813
This will probe the repository for its lock as well.
1815
self._control_files.break_lock()
1816
self.branch.break_lock()
1818
def is_locked(self):
1819
return self._control_files.is_locked()
1821
def _must_be_locked(self):
1822
if not self.is_locked():
1823
raise errors.ObjectNotLocked(self)
1825
def lock_read(self):
1826
"""Lock the tree for reading.
1828
This also locks the branch, and can be unlocked via self.unlock().
1830
:return: A bzrlib.lock.LogicalLockResult.
1832
if not self.is_locked():
1834
self.branch.lock_read()
1836
self._control_files.lock_read()
1837
return LogicalLockResult(self.unlock)
1839
self.branch.unlock()
1842
def lock_tree_write(self):
1843
"""See MutableTree.lock_tree_write, and WorkingTree.unlock.
1845
:return: A bzrlib.lock.LogicalLockResult.
1847
if not self.is_locked():
1849
self.branch.lock_read()
1851
self._control_files.lock_write()
1852
return LogicalLockResult(self.unlock)
1854
self.branch.unlock()
1857
def lock_write(self):
1858
"""See MutableTree.lock_write, and WorkingTree.unlock.
1860
:return: A bzrlib.lock.LogicalLockResult.
1862
if not self.is_locked():
1864
self.branch.lock_write()
1866
self._control_files.lock_write()
1867
return LogicalLockResult(self.unlock)
1869
self.branch.unlock()
1872
def get_physical_lock_status(self):
1873
return self._control_files.get_physical_lock_status()
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
2168
def get_file_sha1(self, file_id, path=None, stat_value=None):
2170
path = self._inventory.id2path(file_id)
2171
return self._hashcache.get_sha1(path, stat_value)
2173
2177
def get_file_mtime(self, file_id, path=None):
2174
2178
"""See Tree.get_file_mtime."""
2176
2180
path = self.inventory.id2path(file_id)
2177
return os.lstat(self.abspath(path)).st_mtime
2182
return os.lstat(self.abspath(path)).st_mtime
2184
if e.errno == errno.ENOENT:
2185
raise errors.FileTimestampUnavailable(path)
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)
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
2195
_is_executable_from_path_and_stat = \
2196
_is_executable_from_path_and_stat_from_basis
2198
def is_executable(self, file_id, path=None):
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)
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)
2213
return self._is_executable_from_path_and_stat_from_stat(path, stat_result)
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
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())
2304
@needs_tree_write_lock
2305
def set_merge_modified(self, modified_hashes):
2307
for file_id, hash in modified_hashes.iteritems():
2308
yield _mod_rio.Stanza(file_id=file_id.decode('utf8'),
2310
self._put_rio('merge-hashes', iter_stanzas(), MERGE_MODIFIED_HEADER_1)
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),
2807
raise errors.BzrRenameFailedError(from_rel, to_rel,
2808
errors.PathsDoNotExist(paths=(from_rel, to_rel)))
2789
2810
raise errors.RenameFailedFilesExist(from_rel, to_rel)
2790
2811
rename_entry.only_change_inv = only_change_inv
3017
3038
supports_versioned_directories = None
3020
def find_format_string(klass, a_bzrdir):
3021
"""Return format name for the working tree object in a_bzrdir."""
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)
3029
def find_format(klass, a_bzrdir):
3030
"""Return the format for the working tree object in a_bzrdir."""
3032
format_string = klass.find_format_string(a_bzrdir)
3033
return format_registry.get(format_string)
3035
raise errors.UnknownFormatError(format=format_string,
3036
kind="working tree")
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.
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()
3068
def get_format_string(self):
3069
"""Return the ASCII format string that identifies this format."""
3070
raise NotImplementedError(self.get_format_string)
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)
3127
def get_controldir_for_branch(self):
3128
"""Get the control directory format for creating branches.
3130
This is to support testing of working tree formats that can not exist
3131
in the same control directory as a branch.
3133
return self._matchingbzrdir
3136
class WorkingTreeFormatMetaDir(bzrdir.BzrDirMetaComponentFormat, WorkingTreeFormat):
3137
"""Base class for working trees that live in bzr meta directories."""
3140
WorkingTreeFormat.__init__(self)
3141
bzrdir.BzrDirMetaComponentFormat.__init__(self)
3144
def find_format_string(klass, controldir):
3145
"""Return format name for the working tree object in controldir."""
3147
transport = controldir.get_workingtree_transport(None)
3148
return transport.get_bytes("format")
3149
except errors.NoSuchFile:
3150
raise errors.NoWorkingTree(base=transport.base)
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',
3130
3160
format_registry.register_lazy("Bazaar Working Tree Format 4 (bzr 0.15)\n",
3131
3161
"bzrlib.workingtree_4", "WorkingTreeFormat4")