/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

Merge from bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
96
96
        deprecated_function,
97
97
        DEPRECATED_PARAMETER,
98
98
        zero_eight,
 
99
        zero_eleven,
99
100
        )
100
101
from bzrlib.trace import mutter, note
101
102
from bzrlib.transform import build_tree
394
395
        return pathjoin(self.basedir, filename)
395
396
    
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.
 
399
        
 
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).
 
402
        """
 
403
        try:
 
404
            revision_id = self.get_parent_ids()[0]
 
405
        except IndexError:
 
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)
 
410
        else:
400
411
            try:
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,
408
419
                                                revision_id)
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
 
422
        # at this point ?
 
423
        try:
 
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
 
428
            # its a ghost.
 
429
            if self.branch.repository.has_revision(revision_id):
 
430
                raise
 
431
            # the basis tree is a ghost so return an empty tree.
 
432
            return self.branch.repository.revision_tree(None)
411
433
 
412
434
    @staticmethod
413
435
    @deprecated_method(zero_eight)
473
495
        This implementation reads the pending merges list and last_revision
474
496
        value and uses that to decide what the parents list should be.
475
497
        """
476
 
        last_rev = self.last_revision()
 
498
        last_rev = self._last_revision()
477
499
        if last_rev is None:
478
500
            parents = []
479
501
        else:
480
502
            parents = [last_rev]
481
 
        other_parents = self.pending_merges()
482
 
        return parents + other_parents
 
503
        try:
 
504
            merges_file = self._control_files.get_utf8('pending-merges')
 
505
        except NoSuchFile:
 
506
            pass
 
507
        else:
 
508
            for l in merges_file.readlines():
 
509
                parents.append(l.rstrip('\n'))
 
510
        return parents
483
511
 
484
512
    def get_root_id(self):
485
513
        """Return the id of this trees root"""
519
547
        if revision_id is None:
520
548
            transform_tree(tree, self)
521
549
        else:
522
 
            # TODO now merge from tree.last_revision to revision
 
550
            # TODO now merge from tree.last_revision to revision (to preserve
 
551
            # user local changes)
523
552
            transform_tree(tree, self)
524
 
            tree.set_last_revision(revision_id)
 
553
            tree.set_parent_ids([revision_id])
525
554
 
526
555
    @needs_write_lock
527
556
    def commit(self, message=None, revprops=None, *args, **kwargs):
537
566
        args = (DEPRECATED_PARAMETER, message, ) + args
538
567
        committed_id = Commit().commit( working_tree=self, revprops=revprops,
539
568
            *args, **kwargs)
540
 
        self._set_inventory(self.read_working_inventory())
541
569
        return committed_id
542
570
 
543
571
    def id2abspath(self, file_id):
644
672
        self._write_inventory(inv)
645
673
 
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.
 
677
 
 
678
        This is equivalent to retrieving the current list of parent ids
 
679
        and setting the list to its value plus revision_id.
 
680
 
 
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.
 
685
        """
 
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)
 
689
 
 
690
    @needs_write_lock
 
691
    def add_parent_tree(self, parent_tuple, allow_leftmost_as_ghost=False):
 
692
        """Add revision_id, tree tuple as a parent.
 
693
 
 
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.
 
699
 
 
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.
 
703
        """
 
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
 
707
            # was.
 
708
            allow_leftmost_as_ghost = True
 
709
        self.set_parent_ids(parent_ids,
 
710
            allow_leftmost_as_ghost=allow_leftmost_as_ghost)
 
711
 
 
712
    @needs_write_lock
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()
651
717
        updated = False
652
718
        for rev_id in revision_ids:
653
 
            if rev_id in p:
 
719
            if rev_id in parents:
654
720
                continue
655
 
            p.append(rev_id)
 
721
            parents.append(rev_id)
656
722
            updated = True
657
723
        if updated:
658
 
            self.set_pending_merges(p)
 
724
            self.set_parent_ids(parents, allow_leftmost_as_ghost=True)
659
725
 
 
726
    @deprecated_method(zero_eleven)
660
727
    @needs_read_lock
661
728
    def pending_merges(self):
662
729
        """Return a list of pending merges.
663
730
 
664
731
        These are revisions that have been merged into the working
665
732
        directory but not yet committed.
666
 
        """
667
 
        try:
668
 
            merges_file = self._control_files.get_utf8('pending-merges')
669
 
        except NoSuchFile:
670
 
            return []
671
 
        p = []
672
 
        for l in merges_file.readlines():
673
 
            p.append(l.rstrip('\n'))
674
 
        return p
 
733
 
 
734
        As of 0.11 this is deprecated. Please see WorkingTree.get_parent_ids()
 
735
        instead - which is available on all tree objects.
 
736
        """
 
737
        return self.get_parent_ids()[1:]
 
738
 
 
739
    @needs_write_lock
 
740
    def set_parent_ids(self, revision_ids, allow_leftmost_as_ghost=False):
 
741
        """Set the parent ids to revision_ids.
 
742
        
 
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.
 
748
 
 
749
        :param revision_ids: The revision_ids to set as the parent ids of this
 
750
            working tree. Any of these may be ghosts.
 
751
        """
 
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)
 
758
        else:
 
759
            self.set_last_revision(None)
 
760
        merges = revision_ids[1:]
 
761
        self._control_files.put_utf8('pending-merges', '\n'.join(merges))
 
762
 
 
763
    @needs_write_lock
 
764
    def set_parent_trees(self, parents_list, allow_leftmost_as_ghost=False):
 
765
        """Set the parents of the working tree.
 
766
 
 
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.
 
770
        """
 
771
        # parent trees are not used in current format trees, delegate to
 
772
        # set_parent_ids
 
773
        self.set_parent_ids([rev for (rev, tree) in parents_list],
 
774
            allow_leftmost_as_ghost=allow_leftmost_as_ghost)
675
775
 
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)
679
782
 
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)
691
794
 
 
795
    @needs_write_lock
 
796
    def merge_from_branch(self, branch, to_revision=None):
 
797
        """Merge from a branch into this working tree.
 
798
 
 
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().
 
804
        """
 
805
        from bzrlib.merge import Merger, Merge3Merger
 
806
        pb = bzrlib.ui.ui_factory.nested_progress_bar()
 
807
        try:
 
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
 
812
            # local alterations
 
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(
 
822
                merger.other_rev_id)
 
823
            merger.pp.next_phase()
 
824
            merger.find_base()
 
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()
 
833
            merger.set_pending()
 
834
        finally:
 
835
            pb.finished()
 
836
        return conflicts
 
837
 
692
838
    @needs_read_lock
693
839
    def merge_modified(self):
694
840
        try:
856
1002
        if not self.has_filename(to_name):
857
1003
            raise BzrError("destination %r not in working directory" % to_abs)
858
1004
        to_dir_id = inv.path2id(to_name)
859
 
        if to_dir_id == None and to_name != '':
 
1005
        if to_dir_id is None and to_name != '':
860
1006
            raise BzrError("destination %r is not a versioned directory" % to_name)
861
1007
        to_dir_ie = inv[to_dir_id]
862
1008
        if to_dir_ie.kind != 'directory':
868
1014
            if not self.has_filename(f):
869
1015
                raise BzrError("%r does not exist in working tree" % f)
870
1016
            f_id = inv.path2id(f)
871
 
            if f_id == None:
 
1017
            if f_id is None:
872
1018
                raise BzrError("%r is not versioned" % f)
873
1019
            name_tail = splitpath(f)[-1]
874
1020
            dest_path = pathjoin(to_name, name_tail)
913
1059
            raise BzrError("can't rename: new working file %r already exists" % to_rel)
914
1060
 
915
1061
        file_id = inv.path2id(from_rel)
916
 
        if file_id == None:
 
1062
        if file_id is None:
917
1063
            raise BzrError("can't rename: old name %r is not versioned" % from_rel)
918
1064
 
919
1065
        entry = inv[file_id]
925
1071
 
926
1072
        to_dir, to_tail = os.path.split(to_rel)
927
1073
        to_dir_id = inv.path2id(to_dir)
928
 
        if to_dir_id == None and to_dir != '':
 
1074
        if to_dir_id is None and to_dir != '':
929
1075
            raise BzrError("can't determine destination directory id for %r" % to_dir)
930
1076
 
931
1077
        mutter("rename_one:")
958
1104
        for subp in self.extras():
959
1105
            if not self.is_ignored(subp):
960
1106
                yield subp
961
 
 
 
1107
    
 
1108
    @needs_write_lock
 
1109
    def unversion(self, file_ids):
 
1110
        """Remove the file ids in file_ids from the current versioned set.
 
1111
 
 
1112
        When a file_id is unversioned, all of its children are automatically
 
1113
        unversioned.
 
1114
 
 
1115
        :param file_ids: The file ids to stop versioning.
 
1116
        :raises: NoSuchId if any fileid is not currently versioned.
 
1117
        """
 
1118
        for file_id in file_ids:
 
1119
            if self._inventory.has_id(file_id):
 
1120
                self._inventory.remove_recursive_id(file_id)
 
1121
            else:
 
1122
                raise errors.NoSuchId(self, file_id)
 
1123
        if len(file_ids):
 
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.
 
1131
            # - RBC 20060907
 
1132
            self._write_inventory(self._inventory)
 
1133
    
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()
998
1170
                try:
 
1171
                    new_basis_tree = self.branch.basis_tree()
999
1172
                    merge_inner(self.branch,
1000
 
                                self.branch.basis_tree(),
1001
 
                                basis_tree, 
1002
 
                                this_tree=self, 
 
1173
                                new_basis_tree,
 
1174
                                basis_tree,
 
1175
                                this_tree=self,
1003
1176
                                pb=pb)
1004
1177
                finally:
1005
1178
                    pb.finished()
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
 
1181
                # tree data.
 
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
 
1189
                     parent in merges])
 
1190
                self.set_parent_trees(parent_trees)
1007
1191
            return count
1008
1192
        finally:
1009
1193
            source.unlock()
1102
1286
        """Yield list of PATH, IGNORE_PATTERN"""
1103
1287
        for subp in self.extras():
1104
1288
            pat = self.is_ignored(subp)
1105
 
            if pat != None:
 
1289
            if pat is not None:
1106
1290
                yield subp, pat
1107
1291
 
1108
1292
    def get_ignore_list(self):
1163
1347
        for regex, mapping in rules:
1164
1348
            match = regex.match(filename)
1165
1349
            if match is not None:
1166
 
                # one or more of the groups in mapping will have a non-None group 
1167
 
                # match.
 
1350
                # one or more of the groups in mapping will have a non-None
 
1351
                # group match.
1168
1352
                groups = match.groups()
1169
1353
                rules = [mapping[group] for group in 
1170
1354
                    mapping if groups[group] is not None]
1174
1358
    def kind(self, file_id):
1175
1359
        return file_kind(self.id2abspath(file_id))
1176
1360
 
1177
 
    @needs_read_lock
1178
1361
    def last_revision(self):
1179
1362
        """Return the last revision id of this working tree.
1180
1363
 
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.
 
1368
 
 
1369
        This was deprecated as of 0.11. Please use get_parent_ids instead.
1184
1370
        """
 
1371
        return self._last_revision()
 
1372
 
 
1373
    @needs_read_lock
 
1374
    def _last_revision(self):
 
1375
        """helper for get_parent_ids."""
1185
1376
        return self.branch.last_revision()
1186
1377
 
1187
1378
    def is_locked(self):
1326
1517
            old_tree = self.basis_tree()
1327
1518
        conflicts = revert(self, old_tree, filenames, backups, pb)
1328
1519
        if not len(filenames):
1329
 
            self.set_pending_merges([])
 
1520
            self.set_parent_ids(self.get_parent_ids()[:1])
1330
1521
            resolve(self)
1331
1522
        else:
1332
1523
            resolve(self, filenames, ignore_misses=True)
1403
1594
        Do a 'normal' merge of the old branch basis if it is relevant.
1404
1595
        """
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.
 
1603
        # 
 
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.
 
1606
        # 
 
1607
        result = 0
1409
1608
        try:
1410
 
            result = 0
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,
1416
 
                                      to_tree,
1417
 
                                      basis,
1418
 
                                      this_tree=self)
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
1426
 
                try:
1427
 
                    base_rev_id = common_ancestor(self.branch.last_revision(),
1428
 
                                                  old_tip,
1429
 
                                                  self.branch.repository)
1430
 
                except errors.NoCommonAncestor:
1431
 
                    base_rev_id = None
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,
1435
 
                                      other_tree,
1436
 
                                      base_tree,
1437
 
                                      this_tree=self)
1438
 
            return result
1439
 
        finally:
1440
 
            self.branch.unlock()
 
1609
            last_rev = self.get_parent_ids()[0]
 
1610
        except IndexError:
 
1611
            last_rev = None
 
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,
 
1617
                                  to_tree,
 
1618
                                  basis,
 
1619
                                  this_tree=self)
 
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]
 
1637
        else:
 
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
 
1649
            try:
 
1650
                base_rev_id = common_ancestor(self.branch.last_revision(),
 
1651
                                              old_tip,
 
1652
                                              self.branch.repository)
 
1653
            except errors.NoCommonAncestor:
 
1654
                base_rev_id = None
 
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,
 
1658
                                  other_tree,
 
1659
                                  base_tree,
 
1660
                                  this_tree=self)
 
1661
        return result
1441
1662
 
1442
1663
    @needs_write_lock
1443
1664
    def _write_inventory(self, inv):
1511
1732
    """
1512
1733
 
1513
1734
    @needs_read_lock
1514
 
    def last_revision(self):
1515
 
        """See WorkingTree.last_revision."""
 
1735
    def _last_revision(self):
 
1736
        """See WorkingTree._last_revision."""
1516
1737
        try:
1517
1738
            return self._control_files.get_utf8('last-revision').read()
1518
1739
        except NoSuchFile:
1702
1923
            finally:
1703
1924
                branch.unlock()
1704
1925
        revision = branch.last_revision()
1705
 
        inv = Inventory() 
 
1926
        inv = Inventory()
1706
1927
        wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
1707
1928
                         branch,
1708
1929
                         inv,
1711
1932
                         _bzrdir=a_bzrdir)
1712
1933
        wt._write_inventory(inv)
1713
1934
        wt.set_root_id(inv.root.file_id)
1714
 
        wt.set_last_revision(revision)
1715
 
        wt.set_pending_merges([])
1716
 
        build_tree(wt.basis_tree(), wt)
 
1935
        basis_tree = branch.repository.revision_tree(revision)
 
1936
        wt.set_parent_trees([(revision, basis_tree)])
 
1937
        build_tree(basis_tree, wt)
1717
1938
        return wt
1718
1939
 
1719
1940
    def __init__(self):
1793
2014
        try:
1794
2015
            wt._write_inventory(inv)
1795
2016
            wt.set_root_id(inv.root.file_id)
1796
 
            wt.set_last_revision(revision_id)
1797
 
            wt.set_pending_merges([])
1798
 
            build_tree(wt.basis_tree(), wt)
 
2017
            basis_tree = branch.repository.revision_tree(revision_id)
 
2018
            if revision_id == bzrlib.revision.NULL_REVISION:
 
2019
                wt.set_parent_trees([])
 
2020
            else:
 
2021
                wt.set_parent_trees([(revision_id, basis_tree)])
 
2022
            build_tree(basis_tree, wt)
1799
2023
        finally:
1800
2024
            wt.unlock()
1801
2025
            control_files.unlock()