394
395
return pathjoin(self.basedir, filename)
396
397
def basis_tree(self):
397
"""Return RevisionTree for the current last revision."""
398
revision_id = self.last_revision()
399
if revision_id is not None:
398
"""Return RevisionTree for the current last revision.
400
If the left most parent is a ghost then the returned tree will be an
401
empty tree - one obtained by calling repository.revision_tree(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)
401
412
xml = self.read_basis_inventory()
402
413
inv = bzrlib.xml5.serializer_v5.read_inventory_from_string(xml)
406
417
if inv is not None and inv.revision_id == revision_id:
407
418
return bzrlib.tree.RevisionTree(self.branch.repository, inv,
409
# FIXME? RBC 20060403 should we cache the inventory here ?
410
return self.branch.repository.revision_tree(revision_id)
420
# No cached copy available, retrieve from the repository.
421
# FIXME? RBC 20060403 should we cache the inventory locally
424
return self.branch.repository.revision_tree(revision_id)
425
except errors.RevisionNotPresent:
426
# the basis tree *may* be a ghost or a low level error may have
427
# occured. If the revision is present, its a problem, if its not
429
if self.branch.repository.has_revision(revision_id):
431
# the basis tree is a ghost so return an empty tree.
432
return self.branch.repository.revision_tree(None)
413
435
@deprecated_method(zero_eight)
644
672
self._write_inventory(inv)
646
674
@needs_write_lock
675
def add_parent_tree_id(self, revision_id, allow_leftmost_as_ghost=False):
676
"""Add revision_id as a parent.
678
This is equivalent to retrieving the current list of parent ids
679
and setting the list to its value plus revision_id.
681
:param revision_id: The revision id to add to the parent list. It may
682
be a ghost revision as long as its not the first parent to be added,
683
or the allow_leftmost_as_ghost parameter is set True.
684
:param allow_leftmost_as_ghost: Allow the first parent to be a ghost.
686
parents = self.get_parent_ids() + [revision_id]
687
self.set_parent_ids(parents,
688
allow_leftmost_as_ghost=len(parents) > 1 or allow_leftmost_as_ghost)
691
def add_parent_tree(self, parent_tuple, allow_leftmost_as_ghost=False):
692
"""Add revision_id, tree tuple as a parent.
694
This is equivalent to retrieving the current list of parent trees
695
and setting the list to its value plus parent_tuple. See also
696
add_parent_tree_id - if you only have a parent id available it will be
697
simpler to use that api. If you have the parent already available, using
698
this api is preferred.
700
:param parent_tuple: The (revision id, tree) to add to the parent list.
701
If the revision_id is a ghost, pass None for the tree.
702
:param allow_leftmost_as_ghost: Allow the first parent to be a ghost.
704
parent_ids = self.get_parent_ids() + [parent_tuple[0]]
705
if len(parent_ids) > 1:
706
# the leftmost may have already been a ghost, preserve that if it
708
allow_leftmost_as_ghost = True
709
self.set_parent_ids(parent_ids,
710
allow_leftmost_as_ghost=allow_leftmost_as_ghost)
647
713
def add_pending_merge(self, *revision_ids):
648
714
# TODO: Perhaps should check at this point that the
649
715
# history of the revision is actually present?
650
p = self.pending_merges()
716
parents = self.get_parent_ids()
652
718
for rev_id in revision_ids:
719
if rev_id in parents:
721
parents.append(rev_id)
658
self.set_pending_merges(p)
724
self.set_parent_ids(parents, allow_leftmost_as_ghost=True)
726
@deprecated_method(zero_eleven)
661
728
def pending_merges(self):
662
729
"""Return a list of pending merges.
664
731
These are revisions that have been merged into the working
665
732
directory but not yet committed.
668
merges_file = self._control_files.get_utf8('pending-merges')
672
for l in merges_file.readlines():
673
p.append(l.rstrip('\n'))
734
As of 0.11 this is deprecated. Please see WorkingTree.get_parent_ids()
735
instead - which is available on all tree objects.
737
return self.get_parent_ids()[1:]
740
def set_parent_ids(self, revision_ids, allow_leftmost_as_ghost=False):
741
"""Set the parent ids to revision_ids.
743
See also set_parent_trees. This api will try to retrieve the tree data
744
for each element of revision_ids from the trees repository. If you have
745
tree data already available, it is more efficient to use
746
set_parent_trees rather than set_parent_ids. set_parent_ids is however
747
an easier API to use.
749
:param revision_ids: The revision_ids to set as the parent ids of this
750
working tree. Any of these may be ghosts.
752
if len(revision_ids) > 0:
753
leftmost_id = revision_ids[0]
754
if (not allow_leftmost_as_ghost and not
755
self.branch.repository.has_revision(leftmost_id)):
756
raise errors.GhostRevisionUnusableHere(leftmost_id)
757
self.set_last_revision(leftmost_id)
759
self.set_last_revision(None)
760
merges = revision_ids[1:]
761
self._control_files.put_utf8('pending-merges', '\n'.join(merges))
764
def set_parent_trees(self, parents_list, allow_leftmost_as_ghost=False):
765
"""Set the parents of the working tree.
767
:param parents_list: A list of (revision_id, tree) tuples.
768
If tree is None, then that element is treated as an unreachable
769
parent tree - i.e. a ghost.
771
# parent trees are not used in current format trees, delegate to
773
self.set_parent_ids([rev for (rev, tree) in parents_list],
774
allow_leftmost_as_ghost=allow_leftmost_as_ghost)
676
776
@needs_write_lock
677
777
def set_pending_merges(self, rev_list):
678
self._control_files.put_utf8('pending-merges', '\n'.join(rev_list))
778
parents = self.get_parent_ids()
779
leftmost = parents[:1]
780
new_parents = leftmost + rev_list
781
self.set_parent_ids(new_parents)
680
783
@needs_write_lock
681
784
def set_merge_modified(self, modified_hashes):
689
792
my_file = rio_file(stanzas, header)
690
793
self._control_files.put(filename, my_file)
796
def merge_from_branch(self, branch, to_revision=None):
797
"""Merge from a branch into this working tree.
799
:param branch: The branch to merge from.
800
:param to_revision: If non-None, the merge will merge to to_revision, but
801
not beyond it. to_revision does not need to be in the history of
802
the branch when it is supplied. If None, to_revision defaults to
803
branch.last_revision().
805
from bzrlib.merge import Merger, Merge3Merger
806
pb = bzrlib.ui.ui_factory.nested_progress_bar()
808
merger = Merger(self.branch, this_tree=self, pb=pb)
809
merger.pp = ProgressPhase("Merge phase", 5, pb)
810
merger.pp.next_phase()
811
# check that there are no
813
merger.check_basis(check_clean=True, require_commits=False)
814
if to_revision is None:
815
to_revision = branch.last_revision()
816
merger.other_rev_id = to_revision
817
if merger.other_rev_id is None:
818
raise error.NoCommits(branch)
819
self.branch.fetch(branch, last_revision=merger.other_rev_id)
820
merger.other_basis = merger.other_rev_id
821
merger.other_tree = self.branch.repository.revision_tree(
823
merger.pp.next_phase()
825
if merger.base_rev_id == merger.other_rev_id:
826
raise errors.PointlessMerge
827
merger.backup_files = False
828
merger.merge_type = Merge3Merger
829
merger.set_interesting_files(None)
830
merger.show_base = False
831
merger.reprocess = False
832
conflicts = merger.do_merge()
693
839
def merge_modified(self):
958
1104
for subp in self.extras():
959
1105
if not self.is_ignored(subp):
1109
def unversion(self, file_ids):
1110
"""Remove the file ids in file_ids from the current versioned set.
1112
When a file_id is unversioned, all of its children are automatically
1115
:param file_ids: The file ids to stop versioning.
1116
:raises: NoSuchId if any fileid is not currently versioned.
1118
for file_id in file_ids:
1119
if self._inventory.has_id(file_id):
1120
self._inventory.remove_recursive_id(file_id)
1122
raise errors.NoSuchId(self, file_id)
1124
# in the future this should just set a dirty bit to wait for the
1125
# final unlock. However, until all methods of workingtree start
1126
# with the current in -memory inventory rather than triggering
1127
# a read, it is more complex - we need to teach read_inventory
1128
# to know when to read, and when to not read first... and possibly
1129
# to save first when the in memory one may be corrupted.
1130
# so for now, we just only write it if it is indeed dirty.
1132
self._write_inventory(self._inventory)
962
1134
@deprecated_method(zero_eight)
963
1135
def iter_conflicts(self):
964
1136
"""List all files in the tree that have text or content conflicts.
996
1168
repository = self.branch.repository
997
1169
pb = bzrlib.ui.ui_factory.nested_progress_bar()
1171
new_basis_tree = self.branch.basis_tree()
999
1172
merge_inner(self.branch,
1000
self.branch.basis_tree(),
1006
self.set_last_revision(self.branch.last_revision())
1179
# TODO - dedup parents list with things merged by pull ?
1180
# reuse the revisiontree we merged against to set the new
1182
parent_trees = [(self.branch.last_revision(), new_basis_tree)]
1183
# we have to pull the merge trees out again, because
1184
# merge_inner has set the ids. - this corner is not yet
1185
# layered well enough to prevent double handling.
1186
merges = self.get_parent_ids()[1:]
1187
parent_trees.extend([
1188
(parent, repository.revision_tree(parent)) for
1190
self.set_parent_trees(parent_trees)
1009
1193
source.unlock()
1174
1358
def kind(self, file_id):
1175
1359
return file_kind(self.id2abspath(file_id))
1178
1361
def last_revision(self):
1179
1362
"""Return the last revision id of this working tree.
1181
In early branch formats this was == the branch last_revision,
1364
In early branch formats this was the same as the branch last_revision,
1182
1365
but that cannot be relied upon - for working tree operations,
1183
always use tree.last_revision().
1366
always use tree.last_revision(). This returns the left most parent id,
1367
or None if there are no parents.
1369
This was deprecated as of 0.11. Please use get_parent_ids instead.
1371
return self._last_revision()
1374
def _last_revision(self):
1375
"""helper for get_parent_ids."""
1185
1376
return self.branch.last_revision()
1187
1378
def is_locked(self):
1403
1594
Do a 'normal' merge of the old branch basis if it is relevant.
1405
1596
old_tip = self.branch.update()
1406
if old_tip is not None:
1407
self.add_pending_merge(old_tip)
1408
self.branch.lock_read()
1597
# here if old_tip is not None, it is the old tip of the branch before
1598
# it was updated from the master branch. This should become a pending
1599
# merge in the working tree to preserve the user existing work. we
1600
# cant set that until we update the working trees last revision to be
1601
# one from the new branch, because it will just get absorbed by the
1602
# parent de-duplication logic.
1604
# We MUST save it even if an error occurs, because otherwise the users
1605
# local work is unreferenced and will appear to have been lost.
1411
if self.last_revision() != self.branch.last_revision():
1412
# merge tree state up to new branch tip.
1413
basis = self.basis_tree()
1414
to_tree = self.branch.basis_tree()
1415
result += merge_inner(self.branch,
1419
self.set_last_revision(self.branch.last_revision())
1420
if old_tip and old_tip != self.last_revision():
1421
# our last revision was not the prior branch last revision
1422
# and we have converted that last revision to a pending merge.
1423
# base is somewhere between the branch tip now
1424
# and the now pending merge
1425
from bzrlib.revision import common_ancestor
1427
base_rev_id = common_ancestor(self.branch.last_revision(),
1429
self.branch.repository)
1430
except errors.NoCommonAncestor:
1432
base_tree = self.branch.repository.revision_tree(base_rev_id)
1433
other_tree = self.branch.repository.revision_tree(old_tip)
1434
result += merge_inner(self.branch,
1440
self.branch.unlock()
1609
last_rev = self.get_parent_ids()[0]
1612
if last_rev != self.branch.last_revision():
1613
# merge tree state up to new branch tip.
1614
basis = self.basis_tree()
1615
to_tree = self.branch.basis_tree()
1616
result += merge_inner(self.branch,
1620
# TODO - dedup parents list with things merged by pull ?
1621
# reuse the tree we've updated to to set the basis:
1622
parent_trees = [(self.branch.last_revision(), to_tree)]
1623
merges = self.get_parent_ids()[1:]
1624
# Ideally we ask the tree for the trees here, that way the working
1625
# tree can decide whether to give us teh entire tree or give us a
1626
# lazy initialised tree. dirstate for instance will have the trees
1627
# in ram already, whereas a last-revision + basis-inventory tree
1628
# will not, but also does not need them when setting parents.
1629
for parent in merges:
1630
parent_trees.append(
1631
(parent, self.branch.repository.revision_tree(parent)))
1632
if old_tip is not None:
1633
parent_trees.append(
1634
(old_tip, self.branch.repository.revision_tree(old_tip)))
1635
self.set_parent_trees(parent_trees)
1636
last_rev = parent_trees[0][0]
1638
# the working tree had the same last-revision as the master
1639
# branch did. We may still have pivot local work from the local
1640
# branch into old_tip:
1641
if old_tip is not None:
1642
self.add_parent_tree_id(old_tip)
1643
if old_tip and old_tip != last_rev:
1644
# our last revision was not the prior branch last revision
1645
# and we have converted that last revision to a pending merge.
1646
# base is somewhere between the branch tip now
1647
# and the now pending merge
1648
from bzrlib.revision import common_ancestor
1650
base_rev_id = common_ancestor(self.branch.last_revision(),
1652
self.branch.repository)
1653
except errors.NoCommonAncestor:
1655
base_tree = self.branch.repository.revision_tree(base_rev_id)
1656
other_tree = self.branch.repository.revision_tree(old_tip)
1657
result += merge_inner(self.branch,
1442
1663
@needs_write_lock
1443
1664
def _write_inventory(self, inv):