/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

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
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).
401
402
        """
402
 
        revision_id = self.last_revision()
403
 
        if revision_id is not None:
 
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:
404
411
            try:
405
412
                xml = self.read_basis_inventory()
406
 
                inv = bzrlib.xml5.serializer_v5.read_inventory_from_string(xml)
407
 
                inv.root.revision = revision_id
408
 
            except NoSuchFile:
409
 
                inv = None
410
 
            if inv is not None and inv.revision_id == revision_id:
411
 
                return bzrlib.tree.RevisionTree(self.branch.repository, inv,
412
 
                                                revision_id)
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, 
 
416
                                                    inv, revision_id)
 
417
            except (NoSuchFile, errors.BadInventoryFormat):
 
418
                pass
 
419
        # No cached copy available, retrieve from the repository.
 
420
        # FIXME? RBC 20060403 should we cache the inventory locally
 
421
        # at this point ?
414
422
        try:
415
423
            return self.branch.repository.revision_tree(revision_id)
416
424
        except errors.RevisionNotPresent:
486
494
        This implementation reads the pending merges list and last_revision
487
495
        value and uses that to decide what the parents list should be.
488
496
        """
489
 
        last_rev = self.last_revision()
 
497
        last_rev = self._last_revision()
490
498
        if last_rev is None:
491
499
            parents = []
492
500
        else:
557
565
        args = (DEPRECATED_PARAMETER, message, ) + args
558
566
        committed_id = Commit().commit( working_tree=self, revprops=revprops,
559
567
            *args, **kwargs)
560
 
        self._set_inventory(self.read_working_inventory())
561
568
        return committed_id
562
569
 
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.
695
702
        """
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
 
706
            # was.
 
707
            allow_leftmost_as_ghost = True
 
708
        self.set_parent_ids(parent_ids,
697
709
            allow_leftmost_as_ghost=allow_leftmost_as_ghost)
698
710
 
699
711
    @needs_write_lock
710
722
        if updated:
711
723
            self.set_parent_ids(parents, allow_leftmost_as_ghost=True)
712
724
 
 
725
    @deprecated_method(zero_eleven)
713
726
    @needs_read_lock
714
727
    def pending_merges(self):
715
728
        """Return a list of pending merges.
716
729
 
717
730
        These are revisions that have been merged into the working
718
731
        directory but not yet committed.
 
732
 
 
733
        As of 0.11 this is deprecated. Please see WorkingTree.get_parent_ids()
 
734
        instead - which is available on all tree objects.
719
735
        """
720
736
        return self.get_parent_ids()[1:]
721
737
 
775
791
        my_file = rio_file(stanzas, header)
776
792
        self._control_files.put(filename, my_file)
777
793
 
 
794
    @needs_write_lock
 
795
    def merge_from_branch(self, branch, to_revision=None):
 
796
        """Merge from a branch into this working tree.
 
797
 
 
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().
 
803
        """
 
804
        from bzrlib.merge import Merger, Merge3Merger
 
805
        pb = bzrlib.ui.ui_factory.nested_progress_bar()
 
806
        try:
 
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
 
811
            # local alterations
 
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(
 
821
                merger.other_rev_id)
 
822
            merger.pp.next_phase()
 
823
            merger.find_base()
 
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()
 
832
            merger.set_pending()
 
833
        finally:
 
834
            pb.finished()
 
835
        return conflicts
 
836
 
778
837
    @needs_read_lock
779
838
    def merge_modified(self):
780
839
        try:
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)
957
 
            if f_id == None:
 
1016
            if f_id is None:
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)
999
1058
            raise BzrError("can't rename: new working file %r already exists" % to_rel)
1000
1059
 
1001
1060
        file_id = inv.path2id(from_rel)
1002
 
        if file_id == None:
 
1061
        if file_id is None:
1003
1062
            raise BzrError("can't rename: old name %r is not versioned" % from_rel)
1004
1063
 
1005
1064
        entry = inv[file_id]
1011
1070
 
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)
1016
1075
 
1017
1076
        mutter("rename_one:")
1044
1103
        for subp in self.extras():
1045
1104
            if not self.is_ignored(subp):
1046
1105
                yield subp
1047
 
 
 
1106
    
 
1107
    @needs_write_lock
 
1108
    def unversion(self, file_ids):
 
1109
        """Remove the file ids in file_ids from the current versioned set.
 
1110
 
 
1111
        When a file_id is unversioned, all of its children are automatically
 
1112
        unversioned.
 
1113
 
 
1114
        :param file_ids: The file ids to stop versioning.
 
1115
        :raises: NoSuchId if any fileid is not currently versioned.
 
1116
        """
 
1117
        for file_id in file_ids:
 
1118
            if self._inventory.has_id(file_id):
 
1119
                self._inventory.remove_recursive_id(file_id)
 
1120
            else:
 
1121
                raise errors.NoSuchId(self, file_id)
 
1122
        if len(file_ids):
 
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.
 
1130
            # - RBC 20060907
 
1131
            self._write_inventory(self._inventory)
 
1132
    
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)
1203
 
            if pat != None:
 
1288
            if pat is not None:
1204
1289
                yield subp, pat
1205
1290
 
1206
1291
    def get_ignore_list(self):
1272
1357
    def kind(self, file_id):
1273
1358
        return file_kind(self.id2abspath(file_id))
1274
1359
 
1275
 
    @needs_read_lock
1276
1360
    def last_revision(self):
1277
1361
        """Return the last revision id of this working tree.
1278
1362
 
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.
 
1367
 
 
1368
        This was deprecated as of 0.11. Please use get_parent_ids instead.
1282
1369
        """
 
1370
        return self._last_revision()
 
1371
 
 
1372
    @needs_read_lock
 
1373
    def _last_revision(self):
 
1374
        """helper for get_parent_ids."""
1283
1375
        return self.branch.last_revision()
1284
1376
 
1285
1377
    def is_locked(self):
1307
1399
        return self._control_files.get_physical_lock_status()
1308
1400
 
1309
1401
    def _basis_inventory_name(self):
1310
 
        return 'basis-inventory'
 
1402
        return 'basis-inventory-cache'
1311
1403
 
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.
1513
1607
        # 
1514
1608
        result = 0
1515
 
        if self.last_revision() != self.branch.last_revision():
 
1609
        try:
 
1610
            last_rev = self.get_parent_ids()[0]
 
1611
        except IndexError:
 
1612
            last_rev = None
 
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]
1539
1638
        else:
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
1634
1733
    """
1635
1734
 
1636
1735
    @needs_read_lock
1637
 
    def last_revision(self):
1638
 
        """See WorkingTree.last_revision."""
 
1736
    def _last_revision(self):
 
1737
        """See WorkingTree._last_revision."""
1639
1738
        try:
1640
1739
            return self._control_files.get_utf8('last-revision').read()
1641
1740
        except NoSuchFile: