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)
644
664
self._write_inventory(inv)
646
666
@needs_write_lock
667
def add_parent_tree_id(self, revision_id, allow_leftmost_as_ghost=False):
668
"""Add revision_id as a parent.
670
This is equivalent to retrieving the current list of parent ids
671
and setting the list to its value plus revision_id.
673
:param revision_id: The revision id to add to the parent list. It may
674
be a ghost revision as long as its not the first parent to be added,
675
or the allow_leftmost_as_ghost parameter is set True.
676
:param allow_leftmost_as_ghost: Allow the first parent to be a ghost.
678
parents = self.get_parent_ids() + [revision_id]
679
self.set_parent_ids(parents,
680
allow_leftmost_as_ghost=len(parents) > 1 or allow_leftmost_as_ghost)
683
def add_parent_tree(self, parent_tuple, allow_leftmost_as_ghost=False):
684
"""Add revision_id, tree tuple as a parent.
686
This is equivalent to retrieving the current list of parent trees
687
and setting the list to its value plus parent_tuple. See also
688
add_parent_tree_id - if you only have a parent id available it will be
689
simpler to use that api. If you have the parent already available, using
690
this api is preferred.
692
:param parent_tuple: The (revision id, tree) to add to the parent list.
693
If the revision_id is a ghost, pass None for the tree.
694
: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]],
697
allow_leftmost_as_ghost=allow_leftmost_as_ghost)
647
700
def add_pending_merge(self, *revision_ids):
648
701
# TODO: Perhaps should check at this point that the
649
702
# history of the revision is actually present?
650
p = self.pending_merges()
703
parents = self.get_parent_ids()
652
705
for rev_id in revision_ids:
706
if rev_id in parents:
708
parents.append(rev_id)
658
self.set_pending_merges(p)
711
self.set_parent_ids(parents, allow_leftmost_as_ghost=True)
661
714
def pending_merges(self):
664
717
These are revisions that have been merged into the working
665
718
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'))
720
return self.get_parent_ids()[1:]
723
def set_parent_ids(self, revision_ids, allow_leftmost_as_ghost=False):
724
"""Set the parent ids to revision_ids.
726
See also set_parent_trees. This api will try to retrieve the tree data
727
for each element of revision_ids from the trees repository. If you have
728
tree data already available, it is more efficient to use
729
set_parent_trees rather than set_parent_ids. set_parent_ids is however
730
an easier API to use.
732
:param revision_ids: The revision_ids to set as the parent ids of this
733
working tree. Any of these may be ghosts.
735
if len(revision_ids) > 0:
736
leftmost_id = revision_ids[0]
737
if (not allow_leftmost_as_ghost and not
738
self.branch.repository.has_revision(leftmost_id)):
739
raise errors.GhostRevisionUnusableHere(leftmost_id)
740
self.set_last_revision(leftmost_id)
742
self.set_last_revision(None)
743
merges = revision_ids[1:]
744
self._control_files.put_utf8('pending-merges', '\n'.join(merges))
747
def set_parent_trees(self, parents_list, allow_leftmost_as_ghost=False):
748
"""Set the parents of the working tree.
750
:param parents_list: A list of (revision_id, tree) tuples.
751
If tree is None, then that element is treated as an unreachable
752
parent tree - i.e. a ghost.
754
# parent trees are not used in current format trees, delegate to
756
self.set_parent_ids([rev for (rev, tree) in parents_list],
757
allow_leftmost_as_ghost=allow_leftmost_as_ghost)
676
759
@needs_write_lock
677
760
def set_pending_merges(self, rev_list):
678
self._control_files.put_utf8('pending-merges', '\n'.join(rev_list))
761
parents = self.get_parent_ids()
762
leftmost = parents[:1]
763
new_parents = leftmost + rev_list
764
self.set_parent_ids(new_parents)
680
766
@needs_write_lock
681
767
def set_merge_modified(self, modified_hashes):
996
1082
repository = self.branch.repository
997
1083
pb = bzrlib.ui.ui_factory.nested_progress_bar()
1085
new_basis_tree = self.branch.basis_tree()
999
1086
merge_inner(self.branch,
1000
self.branch.basis_tree(),
1006
self.set_last_revision(self.branch.last_revision())
1093
# TODO - dedup parents list with things merged by pull ?
1094
# reuse the revisiontree we merged against to set the new
1096
parent_trees = [(self.branch.last_revision(), new_basis_tree)]
1097
# we have to pull the merge trees out again, because
1098
# merge_inner has set the ids. - this corner is not yet
1099
# layered well enough to prevent double handling.
1100
merges = self.get_parent_ids()[1:]
1101
parent_trees.extend([
1102
(parent, repository.revision_tree(parent)) for
1104
self.set_parent_trees(parent_trees)
1009
1107
source.unlock()
1403
1501
Do a 'normal' merge of the old branch basis if it is relevant.
1405
1503
old_tip = self.branch.update()
1406
if old_tip is not None:
1407
self.add_pending_merge(old_tip)
1408
self.branch.lock_read()
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()
1504
# here if old_tip is not None, it is the old tip of the branch before
1505
# it was updated from the master branch. This should become a pending
1506
# merge in the working tree to preserve the user existing work. we
1507
# cant set that until we update the working trees last revision to be
1508
# one from the new branch, because it will just get absorbed by the
1509
# parent de-duplication logic.
1511
# We MUST save it even if an error occurs, because otherwise the users
1512
# local work is unreferenced and will appear to have been lost.
1515
if self.last_revision() != self.branch.last_revision():
1516
# merge tree state up to new branch tip.
1517
basis = self.basis_tree()
1518
to_tree = self.branch.basis_tree()
1519
result += merge_inner(self.branch,
1523
# TODO - dedup parents list with things merged by pull ?
1524
# reuse the tree we've updated to to set the basis:
1525
parent_trees = [(self.branch.last_revision(), to_tree)]
1526
merges = self.get_parent_ids()[1:]
1527
# Ideally we ask the tree for the trees here, that way the working
1528
# tree can decide whether to give us teh entire tree or give us a
1529
# lazy initialised tree. dirstate for instance will have the trees
1530
# in ram already, whereas a last-revision + basis-inventory tree
1531
# will not, but also does not need them when setting parents.
1532
for parent in merges:
1533
parent_trees.append(
1534
(parent, self.branch.repository.revision_tree(parent)))
1535
if old_tip is not None:
1536
parent_trees.append(
1537
(old_tip, self.branch.repository.revision_tree(old_tip)))
1538
self.set_parent_trees(parent_trees)
1540
# the working tree had the same last-revision as the master
1541
# branch did. We may still have pivot local work from the local
1542
# branch into old_tip:
1543
if old_tip is not None:
1544
self.add_parent_tree_id(old_tip)
1545
if old_tip and old_tip != self.last_revision():
1546
# our last revision was not the prior branch last revision
1547
# and we have converted that last revision to a pending merge.
1548
# base is somewhere between the branch tip now
1549
# and the now pending merge
1550
from bzrlib.revision import common_ancestor
1552
base_rev_id = common_ancestor(self.branch.last_revision(),
1554
self.branch.repository)
1555
except errors.NoCommonAncestor:
1557
base_tree = self.branch.repository.revision_tree(base_rev_id)
1558
other_tree = self.branch.repository.revision_tree(old_tip)
1559
result += merge_inner(self.branch,
1442
1565
@needs_write_lock
1443
1566
def _write_inventory(self, inv):