72
73
from bzrlib import symbol_versioning
73
74
from bzrlib.decorators import needs_read_lock, needs_write_lock
74
from bzrlib.i18n import gettext
75
75
from bzrlib.lock import LogicalLockResult
76
76
import bzrlib.mutabletree
77
77
from bzrlib.mutabletree import needs_tree_write_lock
173
173
def __init__(self, basedir='.',
174
174
branch=DEPRECATED_PARAMETER,
179
179
"""Construct a WorkingTree instance. This is not a public API.
193
193
self._branch = self.bzrdir.open_branch()
194
194
self.basedir = realpath(basedir)
195
self._transport = _transport
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()
196
218
self._rules_searcher = None
197
219
self.views = self._make_views()
217
239
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()
219
252
branch = property(
220
253
fget=lambda self: self._branch,
221
254
doc="""The branch this WorkingTree is connected to.
224
257
the working tree has been constructed from.
227
def has_versioned_directories(self):
228
"""See `Tree.has_versioned_directories`."""
229
return self._format.supports_versioned_directories
231
260
def break_lock(self):
232
261
"""Break a lock if one is present from another instance.
237
266
This will probe the repository for its lock as well.
239
raise NotImplementedError(self.break_lock)
268
self._control_files.break_lock()
269
self.branch.break_lock()
241
271
def requires_rich_root(self):
242
272
return self._format.requires_rich_root
277
307
path = osutils.getcwd()
278
control, relpath = controldir.ControlDir.open_containing(path)
308
control, relpath = bzrdir.BzrDir.open_containing(path)
279
309
return control.open_workingtree(), relpath
365
395
return True, tree
366
396
t = transport.get_transport(location)
367
iterator = controldir.ControlDir.find_bzrdirs(t, evaluate=evaluate,
397
iterator = bzrdir.BzrDir.find_bzrdirs(t, evaluate=evaluate,
368
398
list_current=list_current)
369
399
return [tr for tr in iterator if tr is not None]
492
522
raise NotImplementedError(self.get_root_id)
495
def clone(self, to_controldir, revision_id=None):
525
def clone(self, to_bzrdir, revision_id=None):
496
526
"""Duplicate this working tree into to_bzr, including all state.
498
528
Specifically modified files are kept as modified, but
499
529
ignored and unknown files are discarded.
501
If you want to make a new line of development, see ControlDir.sprout()
531
If you want to make a new line of development, see bzrdir.sprout()
504
534
If not None, the cloned tree will have its last revision set to
506
536
and this one merged in.
508
538
# assumes the target bzr dir format is compatible.
509
result = to_controldir.create_workingtree()
539
result = to_bzrdir.create_workingtree()
510
540
self.copy_content_into(result, revision_id)
520
550
# TODO now merge from tree.last_revision to revision (to preserve
521
551
# user local changes)
522
552
merge.transform_tree(tree, self)
523
if revision_id == _mod_revision.NULL_REVISION:
526
new_parents = [revision_id]
527
tree.set_parent_ids(new_parents)
553
tree.set_parent_ids([revision_id])
529
555
def id2abspath(self, file_id):
530
556
return self.abspath(self.id2path(file_id))
740
766
@needs_tree_write_lock
741
767
def set_merge_modified(self, modified_hashes):
742
"""Set the merge modified hashes."""
743
raise NotImplementedError(self.set_merge_modified)
769
for file_id, hash in modified_hashes.iteritems():
770
yield _mod_rio.Stanza(file_id=file_id.decode('utf8'),
772
self._put_rio('merge-hashes', iter_stanzas(), MERGE_MODIFIED_HEADER_1)
745
774
def _sha_from_stat(self, path, stat_result):
746
775
"""Get a sha digest from the tree's stat cache.
784
def _put_rio(self, filename, stanzas, header):
785
self._must_be_locked()
786
my_file = _mod_rio.rio_file(stanzas, header)
787
self._transport.put_file(filename, my_file,
788
mode=self.bzrdir._get_file_mode())
755
790
@needs_write_lock # because merge pulls data into the branch.
756
791
def merge_from_branch(self, branch, to_revision=None, from_revision=None,
757
792
merge_type=None, force=False):
997
1032
show_base=show_base)
998
1033
basis_root_id = basis_tree.get_root_id()
999
1034
new_root_id = new_basis_tree.get_root_id()
1000
if new_root_id is not None and basis_root_id != new_root_id:
1035
if basis_root_id != new_root_id:
1001
1036
self.set_root_id(new_root_id)
1003
1038
basis_tree.unlock()
1004
1039
# TODO - dedup parents list with things merged by pull ?
1005
1040
# reuse the revisiontree we merged against to set the new
1008
if self.branch.last_revision() != _mod_revision.NULL_REVISION:
1009
parent_trees.append(
1010
(self.branch.last_revision(), new_basis_tree))
1042
parent_trees = [(self.branch.last_revision(), new_basis_tree)]
1011
1043
# we have to pull the merge trees out again, because
1012
1044
# merge_inner has set the ids. - this corner is not yet
1013
1045
# layered well enough to prevent double handling.
1137
1170
return _mod_revision.ensure_null(self.branch.last_revision())
1139
1172
def is_locked(self):
1140
"""Check if this tree is locked."""
1141
raise NotImplementedError(self.is_locked)
1173
return self._control_files.is_locked()
1175
def _must_be_locked(self):
1176
if not self.is_locked():
1177
raise errors.ObjectNotLocked(self)
1143
1179
def lock_read(self):
1144
1180
"""Lock the tree for reading.
1148
1184
:return: A bzrlib.lock.LogicalLockResult.
1150
raise NotImplementedError(self.lock_read)
1186
if not self.is_locked():
1188
self.branch.lock_read()
1190
self._control_files.lock_read()
1191
return LogicalLockResult(self.unlock)
1193
self.branch.unlock()
1152
1196
def lock_tree_write(self):
1153
1197
"""See MutableTree.lock_tree_write, and WorkingTree.unlock.
1155
1199
:return: A bzrlib.lock.LogicalLockResult.
1157
raise NotImplementedError(self.lock_tree_write)
1201
if not self.is_locked():
1203
self.branch.lock_read()
1205
self._control_files.lock_write()
1206
return LogicalLockResult(self.unlock)
1208
self.branch.unlock()
1159
1211
def lock_write(self):
1160
1212
"""See MutableTree.lock_write, and WorkingTree.unlock.
1162
1214
:return: A bzrlib.lock.LogicalLockResult.
1164
raise NotImplementedError(self.lock_write)
1216
if not self.is_locked():
1218
self.branch.lock_write()
1220
self._control_files.lock_write()
1221
return LogicalLockResult(self.unlock)
1223
self.branch.unlock()
1166
1226
def get_physical_lock_status(self):
1167
raise NotImplementedError(self.get_physical_lock_status)
1227
return self._control_files.get_physical_lock_status()
1229
def _reset_data(self):
1230
"""Reset transient data that cannot be revalidated."""
1231
raise NotImplementedError(self._reset_data)
1169
1233
def set_last_revision(self, new_revision):
1170
1234
"""Change the last revision in the working tree."""
1464
1528
show_base=show_base)
1465
1529
if nb_conflicts:
1466
1530
self.add_parent_tree((old_tip, other_tree))
1467
note(gettext('Rerun update after fixing the conflicts.'))
1531
note('Rerun update after fixing the conflicts.')
1468
1532
return nb_conflicts
1470
1534
if last_rev != _mod_revision.ensure_null(revision):
1512
1576
last_rev = parent_trees[0][0]
1513
1577
return nb_conflicts
1579
def _write_hashcache_if_dirty(self):
1580
"""Write out the hashcache if it is dirty."""
1581
if self._hashcache.needs_write:
1583
self._hashcache.write()
1585
if e.errno not in (errno.EPERM, errno.EACCES):
1587
# TODO: jam 20061219 Should this be a warning? A single line
1588
# warning might be sufficient to let the user know what
1590
mutter('Could not write hashcache for %s\nError: %s',
1591
self._hashcache.cache_file_name(), e)
1515
1593
def set_conflicts(self, arg):
1516
1594
raise errors.UnsupportedOperation(self.set_conflicts, self)
1746
1824
:param branch: A branch to override probing for the branch.
1748
1826
super(InventoryWorkingTree, self).__init__(basedir=basedir,
1749
branch=branch, _transport=_control_files._transport,
1750
_internal=_internal, _format=_format, _bzrdir=_bzrdir)
1752
self._control_files = _control_files
1753
self._detect_case_handling()
1827
branch=branch, _control_files=_control_files, _internal=_internal,
1828
_format=_format, _bzrdir=_bzrdir)
1755
1830
if _inventory is None:
1756
1831
# This will be acquired on lock_read() or lock_write()
1776
1851
self._inventory = inv
1777
1852
self._inventory_is_modified = dirty
1779
def _detect_case_handling(self):
1780
wt_trans = self.bzrdir.get_workingtree_transport(None)
1782
wt_trans.stat(self._format.case_sensitive_filename)
1783
except errors.NoSuchFile:
1784
self.case_sensitive = True
1786
self.case_sensitive = False
1788
self._setup_directory_is_tree_reference()
1790
1854
def _serialize(self, inventory, out_file):
1791
1855
xml5.serializer_v5.write_inventory(self._inventory, out_file,
1794
1858
def _deserialize(selt, in_file):
1795
1859
return xml5.serializer_v5.read_inventory(in_file)
1797
def break_lock(self):
1798
"""Break a lock if one is present from another instance.
1800
Uses the ui factory to ask for confirmation if the lock may be from
1803
This will probe the repository for its lock as well.
1805
self._control_files.break_lock()
1806
self.branch.break_lock()
1808
def is_locked(self):
1809
return self._control_files.is_locked()
1811
def _must_be_locked(self):
1812
if not self.is_locked():
1813
raise errors.ObjectNotLocked(self)
1815
def lock_read(self):
1816
"""Lock the tree for reading.
1818
This also locks the branch, and can be unlocked via self.unlock().
1820
:return: A bzrlib.lock.LogicalLockResult.
1822
if not self.is_locked():
1824
self.branch.lock_read()
1826
self._control_files.lock_read()
1827
return LogicalLockResult(self.unlock)
1829
self.branch.unlock()
1832
def lock_tree_write(self):
1833
"""See MutableTree.lock_tree_write, and WorkingTree.unlock.
1835
:return: A bzrlib.lock.LogicalLockResult.
1837
if not self.is_locked():
1839
self.branch.lock_read()
1841
self._control_files.lock_write()
1842
return LogicalLockResult(self.unlock)
1844
self.branch.unlock()
1847
def lock_write(self):
1848
"""See MutableTree.lock_write, and WorkingTree.unlock.
1850
:return: A bzrlib.lock.LogicalLockResult.
1852
if not self.is_locked():
1854
self.branch.lock_write()
1856
self._control_files.lock_write()
1857
return LogicalLockResult(self.unlock)
1859
self.branch.unlock()
1862
def get_physical_lock_status(self):
1863
return self._control_files.get_physical_lock_status()
1865
1861
@needs_tree_write_lock
1866
1862
def _write_inventory(self, inv):
1867
1863
"""Write inventory as the current inventory."""
2164
2160
mode=self.bzrdir._get_file_mode())
2165
2161
self._inventory_is_modified = False
2164
def get_file_sha1(self, file_id, path=None, stat_value=None):
2166
path = self._inventory.id2path(file_id)
2167
return self._hashcache.get_sha1(path, stat_value)
2167
2169
def get_file_mtime(self, file_id, path=None):
2168
2170
"""See Tree.get_file_mtime."""
2170
2172
path = self.inventory.id2path(file_id)
2172
return os.lstat(self.abspath(path)).st_mtime
2174
if e.errno == errno.ENOENT:
2175
raise errors.FileTimestampUnavailable(path)
2173
return os.lstat(self.abspath(path)).st_mtime
2178
2175
def _is_executable_from_path_and_stat_from_basis(self, path, stat_result):
2179
2176
file_id = self.path2id(path)
2286
2283
for key, line in annotator.annotate_flat(this_key)]
2287
2284
return annotations
2289
def _put_rio(self, filename, stanzas, header):
2290
self._must_be_locked()
2291
my_file = _mod_rio.rio_file(stanzas, header)
2292
self._transport.put_file(filename, my_file,
2293
mode=self.bzrdir._get_file_mode())
2295
@needs_tree_write_lock
2296
def set_merge_modified(self, modified_hashes):
2298
for file_id, hash in modified_hashes.iteritems():
2299
yield _mod_rio.Stanza(file_id=file_id.decode('utf8'),
2301
self._put_rio('merge-hashes', iter_stanzas(), MERGE_MODIFIED_HEADER_1)
2303
2286
@needs_read_lock
2304
2287
def merge_modified(self):
2305
2288
"""Return a dictionary of files modified by a merge.
3030
3013
supports_versioned_directories = None
3033
def find_format_string(klass, controldir):
3034
"""Return format name for the working tree object in controldir."""
3016
def find_format_string(klass, a_bzrdir):
3017
"""Return format name for the working tree object in a_bzrdir."""
3036
transport = controldir.get_workingtree_transport(None)
3019
transport = a_bzrdir.get_workingtree_transport(None)
3037
3020
return transport.get_bytes("format")
3038
3021
except errors.NoSuchFile:
3039
3022
raise errors.NoWorkingTree(base=transport.base)
3042
def find_format(klass, controldir):
3043
"""Return the format for the working tree object in controldir."""
3025
def find_format(klass, a_bzrdir):
3026
"""Return the format for the working tree object in a_bzrdir."""
3045
format_string = klass.find_format_string(controldir)
3028
format_string = klass.find_format_string(a_bzrdir)
3046
3029
return format_registry.get(format_string)
3047
3030
except KeyError:
3048
3031
raise errors.UnknownFormatError(format=format_string,
3049
3032
kind="working tree")
3051
def initialize(self, controldir, revision_id=None, from_branch=None,
3034
def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
3052
3035
accelerator_tree=None, hardlink=False):
3053
"""Initialize a new working tree in controldir.
3036
"""Initialize a new working tree in a_bzrdir.
3055
:param controldir: ControlDir to initialize the working tree in.
3038
:param a_bzrdir: BzrDir to initialize the working tree in.
3056
3039
:param revision_id: allows creating a working tree at a different
3057
3040
revision than the branch is at.
3058
3041
:param from_branch: Branch to checkout
3139
3122
def unregister_format(klass, format):
3140
3123
format_registry.remove(format)
3142
def get_controldir_for_branch(self):
3143
"""Get the control directory format for creating branches.
3145
This is to support testing of working tree formats that can not exist
3146
in the same control directory as a branch.
3148
return self._matchingbzrdir
3151
3126
format_registry.register_lazy("Bazaar Working Tree Format 4 (bzr 0.15)\n",
3152
3127
"bzrlib.workingtree_4", "WorkingTreeFormat4")