73
72
from bzrlib import symbol_versioning
74
73
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._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()
195
self._transport = _transport
218
196
self._rules_searcher = None
219
197
self.views = self._make_views()
239
217
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
219
branch = property(
253
220
fget=lambda self: self._branch,
254
221
doc="""The branch this WorkingTree is connected to.
257
224
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
260
231
def break_lock(self):
261
232
"""Break a lock if one is present from another instance.
266
237
This will probe the repository for its lock as well.
268
self._control_files.break_lock()
269
self.branch.break_lock()
239
raise NotImplementedError(self.break_lock)
271
241
def requires_rich_root(self):
272
242
return self._format.requires_rich_root
307
277
path = osutils.getcwd()
308
control, relpath = bzrdir.BzrDir.open_containing(path)
278
control, relpath = controldir.ControlDir.open_containing(path)
309
279
return control.open_workingtree(), relpath
395
365
return True, tree
396
366
t = transport.get_transport(location)
397
iterator = bzrdir.BzrDir.find_bzrdirs(t, evaluate=evaluate,
367
iterator = controldir.ControlDir.find_bzrdirs(t, evaluate=evaluate,
398
368
list_current=list_current)
399
369
return [tr for tr in iterator if tr is not None]
522
492
raise NotImplementedError(self.get_root_id)
525
def clone(self, to_bzrdir, revision_id=None):
495
def clone(self, to_controldir, revision_id=None):
526
496
"""Duplicate this working tree into to_bzr, including all state.
528
498
Specifically modified files are kept as modified, but
529
499
ignored and unknown files are discarded.
531
If you want to make a new line of development, see bzrdir.sprout()
501
If you want to make a new line of development, see ControlDir.sprout()
534
504
If not None, the cloned tree will have its last revision set to
536
506
and this one merged in.
538
508
# assumes the target bzr dir format is compatible.
539
result = to_bzrdir.create_workingtree()
509
result = to_controldir.create_workingtree()
540
510
self.copy_content_into(result, revision_id)
550
520
# TODO now merge from tree.last_revision to revision (to preserve
551
521
# user local changes)
552
522
merge.transform_tree(tree, self)
553
tree.set_parent_ids([revision_id])
523
if revision_id == _mod_revision.NULL_REVISION:
526
new_parents = [revision_id]
527
tree.set_parent_ids(new_parents)
555
529
def id2abspath(self, file_id):
556
530
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
572
@needs_tree_write_lock
603
573
def _gather_kinds(self, files, kinds):
604
574
"""See MutableTree._gather_kinds."""
770
740
@needs_tree_write_lock
771
741
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)
742
"""Set the merge modified hashes."""
743
raise NotImplementedError(self.set_merge_modified)
778
745
def _sha_from_stat(self, path, stat_result):
779
746
"""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
755
@needs_write_lock # because merge pulls data into the branch.
795
756
def merge_from_branch(self, branch, to_revision=None, from_revision=None,
796
757
merge_type=None, force=False):
1036
997
show_base=show_base)
1037
998
basis_root_id = basis_tree.get_root_id()
1038
999
new_root_id = new_basis_tree.get_root_id()
1039
if basis_root_id != new_root_id:
1000
if new_root_id is not None and basis_root_id != new_root_id:
1040
1001
self.set_root_id(new_root_id)
1042
1003
basis_tree.unlock()
1043
1004
# TODO - dedup parents list with things merged by pull ?
1044
1005
# reuse the revisiontree we merged against to set the new
1046
parent_trees = [(self.branch.last_revision(), new_basis_tree)]
1008
if self.branch.last_revision() != _mod_revision.NULL_REVISION:
1009
parent_trees.append(
1010
(self.branch.last_revision(), new_basis_tree))
1047
1011
# we have to pull the merge trees out again, because
1048
1012
# merge_inner has set the ids. - this corner is not yet
1049
1013
# layered well enough to prevent double handling.
1174
1137
return _mod_revision.ensure_null(self.branch.last_revision())
1176
1139
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)
1140
"""Check if this tree is locked."""
1141
raise NotImplementedError(self.is_locked)
1183
1143
def lock_read(self):
1184
1144
"""Lock the tree for reading.
1188
1148
: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()
1150
raise NotImplementedError(self.lock_read)
1200
1152
def lock_tree_write(self):
1201
1153
"""See MutableTree.lock_tree_write, and WorkingTree.unlock.
1203
1155
: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()
1157
raise NotImplementedError(self.lock_tree_write)
1215
1159
def lock_write(self):
1216
1160
"""See MutableTree.lock_write, and WorkingTree.unlock.
1218
1162
: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()
1164
raise NotImplementedError(self.lock_write)
1230
1166
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)
1167
raise NotImplementedError(self.get_physical_lock_status)
1237
1169
def set_last_revision(self, new_revision):
1238
1170
"""Change the last revision in the working tree."""
1532
1464
show_base=show_base)
1533
1465
if nb_conflicts:
1534
1466
self.add_parent_tree((old_tip, other_tree))
1535
note('Rerun update after fixing the conflicts.')
1467
note(gettext('Rerun update after fixing the conflicts.'))
1536
1468
return nb_conflicts
1538
1470
if last_rev != _mod_revision.ensure_null(revision):
1580
1512
last_rev = parent_trees[0][0]
1581
1513
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
1515
def set_conflicts(self, arg):
1598
1516
raise errors.UnsupportedOperation(self.set_conflicts, self)
1828
1746
:param branch: A branch to override probing for the branch.
1830
1748
super(InventoryWorkingTree, self).__init__(basedir=basedir,
1831
branch=branch, _control_files=_control_files, _internal=_internal,
1832
_format=_format, _bzrdir=_bzrdir)
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()
1834
1755
if _inventory is None:
1835
1756
# This will be acquired on lock_read() or lock_write()
1855
1776
self._inventory = inv
1856
1777
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()
1858
1790
def _serialize(self, inventory, out_file):
1859
1791
xml5.serializer_v5.write_inventory(self._inventory, out_file,
1862
1794
def _deserialize(selt, in_file):
1863
1795
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
1865
@needs_tree_write_lock
1866
1866
def _write_inventory(self, inv):
1867
1867
"""Write inventory as the current inventory."""
2164
2164
mode=self.bzrdir._get_file_mode())
2165
2165
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
2167
def get_file_mtime(self, file_id, path=None):
2174
2168
"""See Tree.get_file_mtime."""
2176
2170
path = self.inventory.id2path(file_id)
2177
return os.lstat(self.abspath(path)).st_mtime
2172
return os.lstat(self.abspath(path)).st_mtime
2174
if e.errno == errno.ENOENT:
2175
raise errors.FileTimestampUnavailable(path)
2179
2178
def _is_executable_from_path_and_stat_from_basis(self, path, stat_result):
2180
2179
file_id = self.path2id(path)
2287
2286
for key, line in annotator.annotate_flat(this_key)]
2288
2287
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)
2290
2303
@needs_read_lock
2291
2304
def merge_modified(self):
2292
2305
"""Return a dictionary of files modified by a merge.
2782
2795
# something is wrong, so lets determine what exactly
2783
2796
if not self.has_filename(from_rel) and \
2784
2797
not self.has_filename(to_rel):
2785
raise errors.BzrRenameFailedError(from_rel,to_rel,
2786
errors.PathsDoNotExist(paths=(str(from_rel),
2798
raise errors.BzrRenameFailedError(from_rel, to_rel,
2799
errors.PathsDoNotExist(paths=(from_rel, to_rel)))
2789
2801
raise errors.RenameFailedFilesExist(from_rel, to_rel)
2790
2802
rename_entry.only_change_inv = only_change_inv
3017
3029
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,
3031
def initialize(self, controldir, revision_id=None, from_branch=None,
3039
3032
accelerator_tree=None, hardlink=False):
3040
"""Initialize a new working tree in a_bzrdir.
3033
"""Initialize a new working tree in controldir.
3042
:param a_bzrdir: BzrDir to initialize the working tree in.
3035
:param controldir: ControlDir to initialize the working tree in.
3043
3036
:param revision_id: allows creating a working tree at a different
3044
3037
revision than the branch is at.
3045
3038
:param from_branch: Branch to checkout
3065
3058
"""Return the current default format."""
3066
3059
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
3061
def get_format_description(self):
3073
3062
"""Return the short description for this format."""
3074
3063
raise NotImplementedError(self.get_format_description)
3126
3115
def unregister_format(klass, format):
3127
3116
format_registry.remove(format)
3118
def get_controldir_for_branch(self):
3119
"""Get the control directory format for creating branches.
3121
This is to support testing of working tree formats that can not exist
3122
in the same control directory as a branch.
3124
return self._matchingbzrdir
3127
class WorkingTreeFormatMetaDir(bzrdir.BzrDirMetaComponentFormat, WorkingTreeFormat):
3128
"""Base class for working trees that live in bzr meta directories."""
3131
WorkingTreeFormat.__init__(self)
3132
bzrdir.BzrDirMetaComponentFormat.__init__(self)
3135
def find_format_string(klass, controldir):
3136
"""Return format name for the working tree object in controldir."""
3138
transport = controldir.get_workingtree_transport(None)
3139
return transport.get_bytes("format")
3140
except errors.NoSuchFile:
3141
raise errors.NoWorkingTree(base=transport.base)
3144
def find_format(klass, controldir):
3145
"""Return the format for the working tree object in controldir."""
3146
format_string = klass.find_format_string(controldir)
3147
return klass._find_format(format_registry, 'working tree',
3130
3151
format_registry.register_lazy("Bazaar Working Tree Format 4 (bzr 0.15)\n",
3131
3152
"bzrlib.workingtree_4", "WorkingTreeFormat4")