407
411
return bzrlib.tree.RevisionTree(self.branch.repository, inv,
409
413
# FIXME? RBC 20060403 should we cache the inventory here ?
410
return self.branch.repository.revision_tree(revision_id)
415
return self.branch.repository.revision_tree(revision_id)
416
except errors.RevisionNotPresent:
417
# the basis tree *may* be a ghost or a low level error may have
418
# occured. If the revision is present, its a problem, if its not
420
if self.branch.repository.has_revision(revision_id):
422
# the basis tree is a ghost so return an empty tree.
423
return self.branch.repository.revision_tree(None)
413
426
@deprecated_method(zero_eight)
645
665
self._write_inventory(inv)
647
667
@needs_write_lock
668
def add_parent_tree_id(self, revision_id, allow_leftmost_as_ghost=False):
669
"""Add revision_id as a parent.
671
This is equivalent to retrieving the current list of parent ids
672
and setting the list to its value plus revision_id.
674
:param revision_id: The revision id to add to the parent list. It may
675
be a ghost revision as long as its not the first parent to be added,
676
or the allow_leftmost_as_ghost parameter is set True.
677
:param allow_leftmost_as_ghost: Allow the first parent to be a ghost.
679
parents = self.get_parent_ids() + [revision_id]
680
self.set_parent_ids(parents,
681
allow_leftmost_as_ghost=len(parents) > 1 or allow_leftmost_as_ghost)
684
def add_parent_tree(self, parent_tuple, allow_leftmost_as_ghost=False):
685
"""Add revision_id, tree tuple as a parent.
687
This is equivalent to retrieving the current list of parent trees
688
and setting the list to its value plus parent_tuple. See also
689
add_parent_tree_id - if you only have a parent id available it will be
690
simpler to use that api. If you have the parent already available, using
691
this api is preferred.
693
:param parent_tuple: The (revision id, tree) to add to the parent list.
694
If the revision_id is a ghost, pass None for the tree.
695
:param allow_leftmost_as_ghost: Allow the first parent to be a ghost.
697
self.set_parent_ids(self.get_parent_ids() + [parent_tuple[0]],
698
allow_leftmost_as_ghost=allow_leftmost_as_ghost)
648
701
def add_pending_merge(self, *revision_ids):
649
702
# TODO: Perhaps should check at this point that the
650
703
# history of the revision is actually present?
651
p = self.pending_merges()
704
parents = self.get_parent_ids()
653
706
for rev_id in revision_ids:
707
if rev_id in parents:
709
parents.append(rev_id)
659
self.set_pending_merges(p)
712
self.set_parent_ids(parents, allow_leftmost_as_ghost=True)
662
715
def pending_merges(self):
665
718
These are revisions that have been merged into the working
666
719
directory but not yet committed.
669
merges_file = self._control_files.get_utf8('pending-merges')
673
for l in merges_file.readlines():
674
p.append(l.rstrip('\n'))
721
return self.get_parent_ids()[1:]
724
def set_parent_ids(self, revision_ids, allow_leftmost_as_ghost=False):
725
"""Set the parent ids to revision_ids.
727
See also set_parent_trees. This api will try to retrieve the tree data
728
for each element of revision_ids from the trees repository. If you have
729
tree data already available, it is more efficient to use
730
set_parent_trees rather than set_parent_ids. set_parent_ids is however
731
an easier API to use.
733
:param revision_ids: The revision_ids to set as the parent ids of this
734
working tree. Any of these may be ghosts.
736
if len(revision_ids) > 0:
737
leftmost_id = revision_ids[0]
738
if (not allow_leftmost_as_ghost and not
739
self.branch.repository.has_revision(leftmost_id)):
740
raise errors.GhostRevisionUnusableHere(leftmost_id)
741
self.set_last_revision(leftmost_id)
743
self.set_last_revision(None)
744
merges = revision_ids[1:]
745
self._control_files.put_utf8('pending-merges', '\n'.join(merges))
748
def set_parent_trees(self, parents_list, allow_leftmost_as_ghost=False):
749
"""Set the parents of the working tree.
751
:param parents_list: A list of (revision_id, tree) tuples.
752
If tree is None, then that element is treated as an unreachable
753
parent tree - i.e. a ghost.
755
# parent trees are not used in current format trees, delegate to
757
self.set_parent_ids([rev for (rev, tree) in parents_list],
758
allow_leftmost_as_ghost=allow_leftmost_as_ghost)
677
760
@needs_write_lock
678
761
def set_pending_merges(self, rev_list):
679
self._control_files.put_utf8('pending-merges', '\n'.join(rev_list))
762
parents = self.get_parent_ids()
763
leftmost = parents[:1]
764
new_parents = leftmost + rev_list
765
self.set_parent_ids(new_parents)
681
767
@needs_write_lock
682
768
def set_merge_modified(self, modified_hashes):
999
1085
repository = self.branch.repository
1000
1086
pb = bzrlib.ui.ui_factory.nested_progress_bar()
1002
branch_basis = self.branch.basis_tree()
1003
merge_inner(self.branch, branch_basis, basis_tree,
1004
this_tree=self, pb=pb)
1088
new_basis_tree = self.branch.basis_tree()
1089
merge_inner(self.branch,
1005
1094
if (basis_tree.inventory.root is None and
1006
branch_basis.inventory.root is not None):
1007
self.set_root_id(branch_basis.inventory.root.file_id)
1095
new_basis_tree.inventory.root is not None):
1096
self.set_root_id(new_basis_tree.inventory.root.file_id)
1010
self.set_last_revision(self.branch.last_revision())
1099
# TODO - dedup parents list with things merged by pull ?
1100
# reuse the revisiontree we merged against to set the new
1102
parent_trees = [(self.branch.last_revision(), new_basis_tree)]
1103
# we have to pull the merge trees out again, because
1104
# merge_inner has set the ids. - this corner is not yet
1105
# layered well enough to prevent double handling.
1106
merges = self.get_parent_ids()[1:]
1107
parent_trees.extend([
1108
(parent, repository.revision_tree(parent)) for
1110
self.set_parent_trees(parent_trees)
1013
1113
source.unlock()
1413
1513
- Do a 'normal' merge of the old branch basis if it is relevant.
1415
1515
old_tip = self.branch.update()
1416
if old_tip is not None:
1417
self.add_pending_merge(old_tip)
1418
self.branch.lock_read()
1421
if self.last_revision() != self.branch.last_revision():
1422
# merge tree state up to new branch tip.
1423
basis = self.basis_tree()
1424
to_tree = self.branch.basis_tree()
1425
if basis.inventory.root is None:
1426
self.set_root_id(to_tree.inventory.root.file_id)
1427
result += merge_inner(self.branch,
1431
self.set_last_revision(self.branch.last_revision())
1432
if old_tip and old_tip != self.last_revision():
1433
# our last revision was not the prior branch last revision
1434
# and we have converted that last revision to a pending merge.
1435
# base is somewhere between the branch tip now
1436
# and the now pending merge
1437
from bzrlib.revision import common_ancestor
1439
base_rev_id = common_ancestor(self.branch.last_revision(),
1441
self.branch.repository)
1442
except errors.NoCommonAncestor:
1444
base_tree = self.branch.repository.revision_tree(base_rev_id)
1445
other_tree = self.branch.repository.revision_tree(old_tip)
1446
result += merge_inner(self.branch,
1452
self.branch.unlock()
1517
# here if old_tip is not None, it is the old tip of the branch before
1518
# it was updated from the master branch. This should become a pending
1519
# merge in the working tree to preserve the user existing work. we
1520
# cant set that until we update the working trees last revision to be
1521
# one from the new branch, because it will just get absorbed by the
1522
# parent de-duplication logic.
1524
# We MUST save it even if an error occurs, because otherwise the users
1525
# local work is unreferenced and will appear to have been lost.
1528
if self.last_revision() != self.branch.last_revision():
1529
# merge tree state up to new branch tip.
1530
basis = self.basis_tree()
1531
to_tree = self.branch.basis_tree()
1532
if basis.inventory.root is None:
1533
self.set_root_id(to_tree.inventory.root.file_id)
1534
result += merge_inner(self.branch,
1538
# TODO - dedup parents list with things merged by pull ?
1539
# reuse the tree we've updated to to set the basis:
1540
parent_trees = [(self.branch.last_revision(), to_tree)]
1541
merges = self.get_parent_ids()[1:]
1542
# Ideally we ask the tree for the trees here, that way the working
1543
# tree can decide whether to give us teh entire tree or give us a
1544
# lazy initialised tree. dirstate for instance will have the trees
1545
# in ram already, whereas a last-revision + basis-inventory tree
1546
# will not, but also does not need them when setting parents.
1547
for parent in merges:
1548
parent_trees.append(
1549
(parent, self.branch.repository.revision_tree(parent)))
1550
if old_tip is not None:
1551
parent_trees.append(
1552
(old_tip, self.branch.repository.revision_tree(old_tip)))
1553
self.set_parent_trees(parent_trees)
1555
# the working tree had the same last-revision as the master
1556
# branch did. We may still have pivot local work from the local
1557
# branch into old_tip:
1558
if old_tip is not None:
1559
self.add_parent_tree_id(old_tip)
1560
if old_tip and old_tip != self.last_revision():
1561
# our last revision was not the prior branch last revision
1562
# and we have converted that last revision to a pending merge.
1563
# base is somewhere between the branch tip now
1564
# and the now pending merge
1565
from bzrlib.revision import common_ancestor
1567
base_rev_id = common_ancestor(self.branch.last_revision(),
1569
self.branch.repository)
1570
except errors.NoCommonAncestor:
1572
base_tree = self.branch.repository.revision_tree(base_rev_id)
1573
other_tree = self.branch.repository.revision_tree(old_tip)
1574
result += merge_inner(self.branch,
1454
1580
@needs_write_lock
1455
1581
def _write_inventory(self, inv):