399
400
If the left most parent is a ghost then the returned tree will be an
400
401
empty tree - one obtained by calling repository.revision_tree(None).
402
revision_id = self.last_revision()
403
if revision_id is not None:
404
revision_id = self.get_parent_ids()[0]
406
# no parents, return an empty revision tree.
407
# in the future this should return the tree for
408
# 'empty:' - the implicit root empty tree.
409
return self.branch.repository.revision_tree(None)
405
412
xml = self.read_basis_inventory()
406
inv = bzrlib.xml5.serializer_v5.read_inventory_from_string(xml)
407
inv.root.revision = revision_id
410
if inv is not None and inv.revision_id == revision_id:
411
return bzrlib.tree.RevisionTree(self.branch.repository, inv,
413
# FIXME? RBC 20060403 should we cache the inventory here ?
413
inv = bzrlib.xml6.serializer_v6.read_inventory_from_string(xml)
414
if inv is not None and inv.revision_id == revision_id:
415
return bzrlib.tree.RevisionTree(self.branch.repository,
417
except (NoSuchFile, errors.BadInventoryFormat):
419
# No cached copy available, retrieve from the repository.
420
# FIXME? RBC 20060403 should we cache the inventory locally
415
423
return self.branch.repository.revision_tree(revision_id)
416
424
except errors.RevisionNotPresent:
557
565
args = (DEPRECATED_PARAMETER, message, ) + args
558
566
committed_id = Commit().commit( working_tree=self, revprops=revprops,
560
self._set_inventory(self.read_working_inventory())
561
568
return committed_id
563
570
def id2abspath(self, file_id):
693
700
If the revision_id is a ghost, pass None for the tree.
694
701
:param allow_leftmost_as_ghost: Allow the first parent to be a ghost.
696
self.set_parent_ids(self.get_parent_ids() + [parent_tuple[0]],
703
parent_ids = self.get_parent_ids() + [parent_tuple[0]]
704
if len(parent_ids) > 1:
705
# the leftmost may have already been a ghost, preserve that if it
707
allow_leftmost_as_ghost = True
708
self.set_parent_ids(parent_ids,
697
709
allow_leftmost_as_ghost=allow_leftmost_as_ghost)
699
711
@needs_write_lock
711
723
self.set_parent_ids(parents, allow_leftmost_as_ghost=True)
725
@deprecated_method(zero_eleven)
714
727
def pending_merges(self):
715
728
"""Return a list of pending merges.
717
730
These are revisions that have been merged into the working
718
731
directory but not yet committed.
733
As of 0.11 this is deprecated. Please see WorkingTree.get_parent_ids()
734
instead - which is available on all tree objects.
720
736
return self.get_parent_ids()[1:]
775
791
my_file = rio_file(stanzas, header)
776
792
self._control_files.put(filename, my_file)
795
def merge_from_branch(self, branch, to_revision=None):
796
"""Merge from a branch into this working tree.
798
:param branch: The branch to merge from.
799
:param to_revision: If non-None, the merge will merge to to_revision, but
800
not beyond it. to_revision does not need to be in the history of
801
the branch when it is supplied. If None, to_revision defaults to
802
branch.last_revision().
804
from bzrlib.merge import Merger, Merge3Merger
805
pb = bzrlib.ui.ui_factory.nested_progress_bar()
807
merger = Merger(self.branch, this_tree=self, pb=pb)
808
merger.pp = ProgressPhase("Merge phase", 5, pb)
809
merger.pp.next_phase()
810
# check that there are no
812
merger.check_basis(check_clean=True, require_commits=False)
813
if to_revision is None:
814
to_revision = branch.last_revision()
815
merger.other_rev_id = to_revision
816
if merger.other_rev_id is None:
817
raise error.NoCommits(branch)
818
self.branch.fetch(branch, last_revision=merger.other_rev_id)
819
merger.other_basis = merger.other_rev_id
820
merger.other_tree = self.branch.repository.revision_tree(
822
merger.pp.next_phase()
824
if merger.base_rev_id == merger.other_rev_id:
825
raise errors.PointlessMerge
826
merger.backup_files = False
827
merger.merge_type = Merge3Merger
828
merger.set_interesting_files(None)
829
merger.show_base = False
830
merger.reprocess = False
831
conflicts = merger.do_merge()
779
838
def merge_modified(self):
942
1001
if not self.has_filename(to_name):
943
1002
raise BzrError("destination %r not in working directory" % to_abs)
944
1003
to_dir_id = inv.path2id(to_name)
945
if to_dir_id == None and to_name != '':
1004
if to_dir_id is None and to_name != '':
946
1005
raise BzrError("destination %r is not a versioned directory" % to_name)
947
1006
to_dir_ie = inv[to_dir_id]
948
1007
if to_dir_ie.kind != 'directory':
954
1013
if not self.has_filename(f):
955
1014
raise BzrError("%r does not exist in working tree" % f)
956
1015
f_id = inv.path2id(f)
958
1017
raise BzrError("%r is not versioned" % f)
959
1018
name_tail = splitpath(f)[-1]
960
1019
dest_path = pathjoin(to_name, name_tail)
1012
1071
to_dir, to_tail = os.path.split(to_rel)
1013
1072
to_dir_id = inv.path2id(to_dir)
1014
if to_dir_id == None and to_dir != '':
1073
if to_dir_id is None and to_dir != '':
1015
1074
raise BzrError("can't determine destination directory id for %r" % to_dir)
1017
1076
mutter("rename_one:")
1044
1103
for subp in self.extras():
1045
1104
if not self.is_ignored(subp):
1108
def unversion(self, file_ids):
1109
"""Remove the file ids in file_ids from the current versioned set.
1111
When a file_id is unversioned, all of its children are automatically
1114
:param file_ids: The file ids to stop versioning.
1115
:raises: NoSuchId if any fileid is not currently versioned.
1117
for file_id in file_ids:
1118
if self._inventory.has_id(file_id):
1119
self._inventory.remove_recursive_id(file_id)
1121
raise errors.NoSuchId(self, file_id)
1123
# in the future this should just set a dirty bit to wait for the
1124
# final unlock. However, until all methods of workingtree start
1125
# with the current in -memory inventory rather than triggering
1126
# a read, it is more complex - we need to teach read_inventory
1127
# to know when to read, and when to not read first... and possibly
1128
# to save first when the in memory one may be corrupted.
1129
# so for now, we just only write it if it is indeed dirty.
1131
self._write_inventory(self._inventory)
1048
1133
@deprecated_method(zero_eight)
1049
1134
def iter_conflicts(self):
1050
1135
"""List all files in the tree that have text or content conflicts.
1200
1285
"""Yield list of PATH, IGNORE_PATTERN"""
1201
1286
for subp in self.extras():
1202
1287
pat = self.is_ignored(subp)
1204
1289
yield subp, pat
1206
1291
def get_ignore_list(self):
1272
1357
def kind(self, file_id):
1273
1358
return file_kind(self.id2abspath(file_id))
1276
1360
def last_revision(self):
1277
1361
"""Return the last revision id of this working tree.
1279
In early branch formats this was == the branch last_revision,
1363
In early branch formats this was the same as the branch last_revision,
1280
1364
but that cannot be relied upon - for working tree operations,
1281
always use tree.last_revision().
1365
always use tree.last_revision(). This returns the left most parent id,
1366
or None if there are no parents.
1368
This was deprecated as of 0.11. Please use get_parent_ids instead.
1370
return self._last_revision()
1373
def _last_revision(self):
1374
"""helper for get_parent_ids."""
1283
1375
return self.branch.last_revision()
1285
1377
def is_locked(self):
1307
1399
return self._control_files.get_physical_lock_status()
1309
1401
def _basis_inventory_name(self):
1310
return 'basis-inventory'
1402
return 'basis-inventory-cache'
1312
1404
@needs_write_lock
1313
1405
def set_last_revision(self, new_revision):
1348
1440
# root node id can legitimately look like 'revision_id' but cannot
1349
1441
# contain a '"'.
1350
1442
xml = self.branch.repository.get_inventory_xml(new_revision)
1351
if not 'revision_id="' in xml.split('\n', 1)[0]:
1443
firstline = xml.split('\n', 1)[0]
1444
if (not 'revision_id="' in firstline or
1445
'format="6"' not in firstline):
1352
1446
inv = self.branch.repository.deserialise_inventory(
1353
1447
new_revision, xml)
1354
1448
inv.revision_id = new_revision
1355
xml = bzrlib.xml5.serializer_v5.write_inventory_to_string(inv)
1449
xml = bzrlib.xml6.serializer_v6.write_inventory_to_string(inv)
1356
1450
assert isinstance(xml, str), 'serialised xml must be bytestring.'
1357
1451
path = self._basis_inventory_name()
1358
1452
sio = StringIO(xml)
1512
1606
# local work is unreferenced and will appear to have been lost.
1515
if self.last_revision() != self.branch.last_revision():
1610
last_rev = self.get_parent_ids()[0]
1613
if last_rev != self.branch.last_revision():
1516
1614
# merge tree state up to new branch tip.
1517
1615
basis = self.basis_tree()
1518
1616
to_tree = self.branch.basis_tree()
1536
1634
parent_trees.append(
1537
1635
(old_tip, self.branch.repository.revision_tree(old_tip)))
1538
1636
self.set_parent_trees(parent_trees)
1637
last_rev = parent_trees[0][0]
1540
1639
# the working tree had the same last-revision as the master
1541
1640
# branch did. We may still have pivot local work from the local
1542
1641
# branch into old_tip:
1543
1642
if old_tip is not None:
1544
1643
self.add_parent_tree_id(old_tip)
1545
if old_tip and old_tip != self.last_revision():
1644
if old_tip and old_tip != last_rev:
1546
1645
# our last revision was not the prior branch last revision
1547
1646
# and we have converted that last revision to a pending merge.
1548
1647
# base is somewhere between the branch tip now