123
120
ERROR_PATH_NOT_FOUND = 3 # WindowsError errno code, equivalent to ENOENT
126
@deprecated_function(zero_thirteen)
127
def gen_file_id(name):
128
"""Return new file id for the basename 'name'.
130
Use bzrlib.generate_ids.gen_file_id() instead
132
return generate_ids.gen_file_id(name)
135
@deprecated_function(zero_thirteen)
137
"""Return a new tree-root file id.
139
This has been deprecated in favor of bzrlib.generate_ids.gen_root_id()
141
return generate_ids.gen_root_id()
144
123
class TreeEntry(object):
145
124
"""An entry that implements the minimum interface used by commands.
222
201
if not _internal:
223
202
raise errors.BzrError("Please use bzrdir.open_workingtree or "
224
203
"WorkingTree.open() to obtain a WorkingTree.")
225
assert isinstance(basedir, basestring), \
226
"base directory %r is not a string" % basedir
227
204
basedir = safe_unicode(basedir)
228
205
mutter("opening working tree %r", basedir)
229
206
if deprecated_passed(branch):
237
214
self._control_files = self.branch.control_files
239
216
# assume all other formats have their own control files.
240
assert isinstance(_control_files, LockableFiles), \
241
"_control_files must be a LockableFiles, not %r" \
243
217
self._control_files = _control_files
218
self._transport = self._control_files._transport
244
219
# update the whole cache up front and write to disk if anything changed;
245
220
# in the future we might want to do this more selectively
246
221
# two possible ways offer themselves : in self._unlock, write the cache
250
225
wt_trans = self.bzrdir.get_workingtree_transport(None)
251
226
cache_filename = wt_trans.local_abspath('stat-cache')
252
227
self._hashcache = hashcache.HashCache(basedir, cache_filename,
253
self._control_files._file_mode)
228
self.bzrdir._get_file_mode())
254
229
hc = self._hashcache
256
231
# is this scan needed ? it makes things kinda slow.
434
408
def _cleanup(self):
435
409
self._flush_ignore_list_cache()
438
@deprecated_method(zero_eight)
439
def create(branch, directory):
440
"""Create a workingtree for branch at directory.
442
If existing_directory already exists it must have a .bzr directory.
443
If it does not exist, it will be created.
445
This returns a new WorkingTree object for the new checkout.
447
TODO FIXME RBC 20060124 when we have checkout formats in place this
448
should accept an optional revisionid to checkout [and reject this if
449
checking out into the same dir as a pre-checkout-aware branch format.]
451
XXX: When BzrDir is present, these should be created through that
454
warnings.warn('delete WorkingTree.create', stacklevel=3)
455
transport = get_transport(directory)
456
if branch.bzrdir.root_transport.base == transport.base:
458
return branch.bzrdir.create_workingtree()
459
# different directory,
460
# create a branch reference
461
# and now a working tree.
462
raise NotImplementedError
465
@deprecated_method(zero_eight)
466
def create_standalone(directory):
467
"""Create a checkout and a branch and a repo at directory.
469
Directory must exist and be empty.
471
please use BzrDir.create_standalone_workingtree
473
return bzrdir.BzrDir.create_standalone_workingtree(directory)
475
411
def relpath(self, path):
476
412
"""Return the local path portion from a given path.
618
554
__contains__ = has_id
620
556
def get_file_size(self, file_id):
621
return os.path.getsize(self.id2abspath(file_id))
557
"""See Tree.get_file_size"""
559
return os.path.getsize(self.id2abspath(file_id))
561
if e.errno != errno.ENOENT:
624
567
def get_file_sha1(self, file_id, path=None, stat_value=None):
664
607
# function - they should be part of lock_write and unlock.
665
608
inv = self.inventory
666
609
for f, file_id, kind in zip(files, ids, kinds):
667
assert kind is not None
668
610
if file_id is None:
669
611
inv.add_path(f, kind=kind)
766
708
return (kind, None, None, None)
768
@deprecated_method(zero_eleven)
770
def pending_merges(self):
771
"""Return a list of pending merges.
773
These are revisions that have been merged into the working
774
directory but not yet committed.
776
As of 0.11 this is deprecated. Please see WorkingTree.get_parent_ids()
777
instead - which is available on all tree objects.
779
return self.get_parent_ids()[1:]
781
710
def _check_parents_for_ghosts(self, revision_ids, allow_leftmost_as_ghost):
782
711
"""Common ghost checking functionality from set_parent_*.
793
722
def _set_merges_from_parent_ids(self, parent_ids):
794
723
merges = parent_ids[1:]
795
self._control_files.put_bytes('pending-merges', '\n'.join(merges))
724
self._transport.put_bytes('pending-merges', '\n'.join(merges),
725
mode=self._control_files._file_mode)
797
727
@needs_tree_write_lock
798
728
def set_parent_ids(self, revision_ids, allow_leftmost_as_ghost=False):
874
804
def _put_rio(self, filename, stanzas, header):
875
805
self._must_be_locked()
876
806
my_file = rio_file(stanzas, header)
877
self._control_files.put(filename, my_file)
807
self._transport.put_file(filename, my_file,
808
mode=self._control_files._file_mode)
879
810
@needs_write_lock # because merge pulls data into the branch.
880
811
def merge_from_branch(self, branch, to_revision=None, from_revision=None,
1102
1033
sio = StringIO()
1103
1034
self._serialize(self._inventory, sio)
1105
self._control_files.put('inventory', sio)
1036
self._transport.put_file('inventory', sio,
1037
mode=self._control_files._file_mode)
1106
1038
self._inventory_is_modified = False
1108
1040
def _kind(self, relpath):
1269
1201
DeprecationWarning)
1271
1203
# check destination directory
1272
assert not isinstance(from_paths, basestring)
1204
if isinstance(from_paths, basestring):
1273
1206
inv = self.inventory
1274
1207
to_abs = self.abspath(to_dir)
1275
1208
if not isdir(to_abs):
1539
1472
# - RBC 20060907
1540
1473
self._write_inventory(self._inventory)
1542
@deprecated_method(zero_eight)
1543
def iter_conflicts(self):
1544
"""List all files in the tree that have text or content conflicts.
1545
DEPRECATED. Use conflicts instead."""
1546
return self._iter_conflicts()
1548
1475
def _iter_conflicts(self):
1549
1476
conflicted = set()
1550
1477
for info in self.list_files():
1793
1720
def _reset_data(self):
1794
1721
"""Reset transient data that cannot be revalidated."""
1795
1722
self._inventory_is_modified = False
1796
result = self._deserialize(self._control_files.get('inventory'))
1723
result = self._deserialize(self._transport.get('inventory'))
1797
1724
self._set_inventory(result, dirty=False)
1799
1726
@needs_tree_write_lock
1821
1748
def _write_basis_inventory(self, xml):
1822
1749
"""Write the basis inventory XML to the basis-inventory file"""
1823
assert isinstance(xml, str), 'serialised xml must be bytestring.'
1824
1750
path = self._basis_inventory_name()
1825
1751
sio = StringIO(xml)
1826
self._control_files.put(path, sio)
1752
self._transport.put_file(path, sio,
1753
mode=self._control_files._file_mode)
1828
1755
def _create_basis_xml_from_inventory(self, revision_id, inventory):
1829
1756
"""Create the text that will be saved in basis-inventory"""
1860
1787
def read_basis_inventory(self):
1861
1788
"""Read the cached basis inventory."""
1862
1789
path = self._basis_inventory_name()
1863
return self._control_files.get(path).read()
1790
return self._transport.get_bytes(path)
1865
1792
@needs_read_lock
1866
1793
def read_working_inventory(self):
1876
1803
if self._inventory_is_modified:
1877
1804
raise errors.InventoryModified(self)
1878
result = self._deserialize(self._control_files.get('inventory'))
1805
result = self._deserialize(self._transport.get('inventory'))
1879
1806
self._set_inventory(result, dirty=False)
2090
2017
"""Set the root id for this tree."""
2091
2018
# for compatability
2092
2019
if file_id is None:
2093
symbol_versioning.warn(symbol_versioning.zero_twelve
2094
% 'WorkingTree.set_root_id with fileid=None',
2099
file_id = osutils.safe_file_id(file_id)
2021
'WorkingTree.set_root_id with fileid=None')
2022
file_id = osutils.safe_file_id(file_id)
2100
2023
self._set_root_id(file_id)
2102
2025
def _set_root_id(self, file_id):
2582
2505
def _last_revision(self):
2583
2506
"""See Mutable.last_revision."""
2585
return self._control_files.get('last-revision').read()
2508
return self._transport.get_bytes('last-revision')
2586
2509
except errors.NoSuchFile:
2587
2510
return _mod_revision.NULL_REVISION
2590
2513
"""See WorkingTree._change_last_revision."""
2591
2514
if revision_id is None or revision_id == NULL_REVISION:
2593
self._control_files._transport.delete('last-revision')
2516
self._transport.delete('last-revision')
2594
2517
except errors.NoSuchFile:
2598
self._control_files.put_bytes('last-revision', revision_id)
2521
self._transport.put_bytes('last-revision', revision_id,
2522
mode=self._control_files._file_mode)
2601
2525
@needs_tree_write_lock
2644
2568
return path[:-len(suffix)]
2647
@deprecated_function(zero_eight)
2648
def is_control_file(filename):
2649
"""See WorkingTree.is_control_filename(filename)."""
2650
## FIXME: better check
2651
filename = normpath(filename)
2652
while filename != '':
2653
head, tail = os.path.split(filename)
2654
## mutter('check %r for control file' % ((head, tail),))
2657
if filename == head:
2663
2571
class WorkingTreeFormat(object):
2664
2572
"""An encapsulation of the initialization and open routines for a format.
2755
2662
"""See WorkingTreeFormat.get_format_description()."""
2756
2663
return "Working tree format 2"
2758
def stub_initialize_remote(self, control_files):
2759
"""As a special workaround create critical control files for a remote working tree
2665
def _stub_initialize_remote(self, branch):
2666
"""As a special workaround create critical control files for a remote working tree.
2761
2668
This ensures that it can later be updated and dealt with locally,
2762
2669
since BzrDirFormat6 and BzrDirFormat5 cannot represent dirs with
2766
2673
inv = Inventory()
2767
2674
xml5.serializer_v5.write_inventory(inv, sio, working=True)
2769
control_files.put('inventory', sio)
2771
control_files.put_bytes('pending-merges', '')
2676
branch._transport.put_file('inventory', sio,
2677
mode=branch.control_files._file_mode)
2678
branch._transport.put_bytes('pending-merges', '',
2679
mode=branch.control_files._file_mode)
2774
2682
def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
2883
2791
control_files = self._open_control_files(a_bzrdir)
2884
2792
control_files.create_lock()
2885
2793
control_files.lock_write()
2886
control_files.put_utf8('format', self.get_format_string())
2794
transport.put_bytes('format', self.get_format_string(),
2795
mode=control_files._file_mode)
2887
2796
if from_branch is not None:
2888
2797
branch = from_branch