159
161
return gen_file_id('TREE_ROOT')
162
def needs_tree_write_lock(unbound):
163
"""Decorate unbound to take out and release a tree_write lock."""
164
def tree_write_locked(self, *args, **kwargs):
165
self.lock_tree_write()
167
return unbound(self, *args, **kwargs)
170
tree_write_locked.__doc__ = unbound.__doc__
171
tree_write_locked.__name__ = unbound.__name__
172
return tree_write_locked
175
164
class TreeEntry(object):
176
165
"""An entry that implements the minimum interface used by commands.
338
327
def _set_inventory(self, inv):
339
328
assert inv.root is not None
340
329
self._inventory = inv
341
self.path2id = self._inventory.path2id
343
def is_control_filename(self, filename):
344
"""True if filename is the name of a control file in this tree.
346
:param filename: A filename within the tree. This is a relative path
347
from the root of this tree.
349
This is true IF and ONLY IF the filename is part of the meta data
350
that bzr controls in this tree. I.E. a random .bzr directory placed
351
on disk will not be a control file for this tree.
353
return self.bzrdir.is_control_filename(filename)
356
332
def open(path=None, _unsupported=False):
564
540
transform_tree(tree, self)
565
541
tree.set_parent_ids([revision_id])
568
def commit(self, message=None, revprops=None, *args, **kwargs):
569
# avoid circular imports
570
from bzrlib.commit import Commit
573
if not 'branch-nick' in revprops:
574
revprops['branch-nick'] = self.branch.nick
575
# args for wt.commit start at message from the Commit.commit method,
576
# but with branch a kwarg now, passing in args as is results in the
577
#message being used for the branch
578
args = (DEPRECATED_PARAMETER, message, ) + args
579
committed_id = Commit().commit( working_tree=self, revprops=revprops,
583
543
def id2abspath(self, file_id):
584
544
return self.abspath(self.id2path(file_id))
622
582
mode = os.lstat(self.abspath(path)).st_mode
623
583
return bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
625
@needs_tree_write_lock
626
def add(self, files, ids=None):
627
"""Make files versioned.
629
Note that the command line normally calls smart_add instead,
630
which can automatically recurse.
632
This adds the files to the inventory, so that they will be
633
recorded by the next commit.
636
List of paths to add, relative to the base of the tree.
639
If set, use these instead of automatically generated ids.
640
Must be the same length as the list of files, but may
641
contain None for ids that are to be autogenerated.
643
TODO: Perhaps have an option to add the ids even if the files do
646
TODO: Perhaps callback with the ids and paths as they're added.
586
def _add(self, files, ids, kinds):
587
"""See MutableTree._add."""
648
588
# TODO: Re-adding a file that is removed in the working copy
649
589
# should probably put it back with the previous ID.
650
if isinstance(files, basestring):
651
assert(ids is None or isinstance(ids, basestring))
657
ids = [None] * len(files)
659
assert(len(ids) == len(files))
590
# the read and write working inventory should not occur in this
591
# function - they should be part of lock_write and unlock.
661
592
inv = self.read_working_inventory()
662
for f,file_id in zip(files, ids):
663
if self.is_control_filename(f):
664
raise errors.ForbiddenControlFileError(filename=f)
669
raise BzrError("cannot add top-level %r" % f)
671
fullpath = normpath(self.abspath(f))
673
kind = file_kind(fullpath)
675
if e.errno == errno.ENOENT:
676
raise NoSuchFile(fullpath)
677
if not InventoryEntry.versionable_kind(kind):
678
raise errors.BadFileKindError(filename=f, kind=kind)
593
for f, file_id, kind in zip(files, ids, kinds):
594
assert kind is not None
679
595
if file_id is None:
680
596
inv.add_path(f, kind=kind)
682
598
inv.add_path(f, kind=kind, file_id=file_id)
684
599
self._write_inventory(inv)
686
601
@needs_tree_write_lock
602
def _gather_kinds(self, files, kinds):
603
"""See MutableTree._gather_kinds."""
604
for pos, f in enumerate(files):
605
if kinds[pos] is None:
606
fullpath = normpath(self.abspath(f))
608
kinds[pos] = file_kind(fullpath)
610
if e.errno == errno.ENOENT:
611
raise NoSuchFile(fullpath)
687
614
def add_parent_tree_id(self, revision_id, allow_leftmost_as_ghost=False):
688
615
"""Add revision_id as a parent.
775
702
@needs_tree_write_lock
776
703
def set_parent_trees(self, parents_list, allow_leftmost_as_ghost=False):
777
"""Set the parents of the working tree.
779
:param parents_list: A list of (revision_id, tree) tuples.
780
If tree is None, then that element is treated as an unreachable
781
parent tree - i.e. a ghost.
704
"""See MutableTree.set_parent_trees."""
783
705
# parent trees are not used in current format trees, delegate to
785
707
self.set_parent_ids([rev for (rev, tree) in parents_list],
868
790
merge_hashes[file_id] = hash
869
791
return merge_hashes
794
def mkdir(self, path, file_id=None):
795
"""See MutableTree.mkdir()."""
797
file_id = gen_file_id(os.path.basename(path))
798
os.mkdir(self.abspath(path))
799
self.add(path, file_id, 'directory')
871
802
def get_symlink_target(self, file_id):
872
803
return os.readlink(self.id2abspath(file_id))
1370
1311
return file_kind(self.id2abspath(file_id))
1372
1313
def last_revision(self):
1373
"""Return the last revision id of this working tree.
1375
In early branch formats this was the same as the branch last_revision,
1376
but that cannot be relied upon - for working tree operations,
1377
always use tree.last_revision(). This returns the left most parent id,
1378
or None if there are no parents.
1380
This was deprecated as of 0.11. Please use get_parent_ids instead.
1314
"""Return the last revision of the branch for this tree.
1316
This format tree does not support a separate marker for last-revision
1317
compared to the branch.
1319
See MutableTree.last_revision
1382
1321
return self._last_revision()
1401
1340
def lock_tree_write(self):
1402
"""Lock the working tree for write, and the branch for read.
1404
This is useful for operations which only need to mutate the working
1405
tree. Taking out branch write locks is a relatively expensive process
1406
and may fail if the branch is on read only media. So branch write locks
1407
should only be taken out when we are modifying branch data - such as in
1408
operations like commit, pull, uncommit and update.
1341
"""See MutableTree.lock_tree_write, and WorkingTree.unlock."""
1410
1342
self.branch.lock_read()
1412
1344
return self._control_files.lock_write()