~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transform.py

  • Committer: Martin Pool
  • Date: 2006-03-10 06:29:53 UTC
  • mfrom: (1608 +trunk)
  • mto: This revision was merged to the branch mainline in revision 1611.
  • Revision ID: mbp@sourcefrog.net-20060310062953-bc1c7ade75c89a7a
[merge] bzr.dev; pycurl not updated for readv yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
                           ExistingLimbo, ImmortalLimbo)
24
24
from bzrlib.inventory import InventoryEntry
25
25
from bzrlib.osutils import file_kind, supports_executable, pathjoin
26
 
from bzrlib.progress import DummyProgress
 
26
from bzrlib.progress import DummyProgress, ProgressPhase
27
27
from bzrlib.trace import mutter, warning
 
28
import bzrlib.ui 
28
29
 
29
30
 
30
31
ROOT_PARENT = "root-parent"
36
37
    map[key] = value
37
38
 
38
39
 
 
40
class _TransformResults(object):
 
41
    def __init__(self, modified_paths):
 
42
        object.__init__(self)
 
43
        self.modified_paths = modified_paths
 
44
 
 
45
 
39
46
class TreeTransform(object):
40
47
    """Represent a tree transformation.
41
48
    
659
666
            raise MalformedTransform(conflicts=conflicts)
660
667
        limbo_inv = {}
661
668
        inv = self._tree.inventory
662
 
        self._apply_removals(inv, limbo_inv)
663
 
        self._apply_insertions(inv, limbo_inv)
 
669
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
 
670
        try:
 
671
            child_pb.update('Apply phase', 0, 2)
 
672
            self._apply_removals(inv, limbo_inv)
 
673
            child_pb.update('Apply phase', 1, 2)
 
674
            modified_paths = self._apply_insertions(inv, limbo_inv)
 
675
        finally:
 
676
            child_pb.finished()
664
677
        self._tree._write_inventory(inv)
665
678
        self.__done = True
666
679
        self.finalize()
 
680
        return _TransformResults(modified_paths)
667
681
 
668
682
    def _limbo_name(self, trans_id):
669
683
        """Generate the limbo name of a file"""
678
692
        """
679
693
        tree_paths = list(self._tree_path_ids.iteritems())
680
694
        tree_paths.sort(reverse=True)
681
 
        for num, data in enumerate(tree_paths):
682
 
            path, trans_id = data
683
 
            self._pb.update('removing file', num+1, len(tree_paths))
684
 
            full_path = self._tree.abspath(path)
685
 
            if trans_id in self._removed_contents:
686
 
                self.delete_any(full_path)
687
 
            elif trans_id in self._new_name or trans_id in self._new_parent:
688
 
                try:
689
 
                    os.rename(full_path, self._limbo_name(trans_id))
690
 
                except OSError, e:
691
 
                    if e.errno != errno.ENOENT:
692
 
                        raise
693
 
            if trans_id in self._removed_id:
694
 
                if trans_id == self._new_root:
695
 
                    file_id = self._tree.inventory.root.file_id
696
 
                else:
 
695
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
 
696
        try:
 
697
            for num, data in enumerate(tree_paths):
 
698
                path, trans_id = data
 
699
                child_pb.update('removing file', num, len(tree_paths))
 
700
                full_path = self._tree.abspath(path)
 
701
                if trans_id in self._removed_contents:
 
702
                    self.delete_any(full_path)
 
703
                elif trans_id in self._new_name or trans_id in \
 
704
                    self._new_parent:
 
705
                    try:
 
706
                        os.rename(full_path, self._limbo_name(trans_id))
 
707
                    except OSError, e:
 
708
                        if e.errno != errno.ENOENT:
 
709
                            raise
 
710
                if trans_id in self._removed_id:
 
711
                    if trans_id == self._new_root:
 
712
                        file_id = self._tree.inventory.root.file_id
 
713
                    else:
 
714
                        file_id = self.tree_file_id(trans_id)
 
715
                    del inv[file_id]
 
716
                elif trans_id in self._new_name or trans_id in self._new_parent:
697
717
                    file_id = self.tree_file_id(trans_id)
698
 
                del inv[file_id]
699
 
            elif trans_id in self._new_name or trans_id in self._new_parent:
700
 
                file_id = self.tree_file_id(trans_id)
701
 
                if file_id is not None:
702
 
                    limbo_inv[trans_id] = inv[file_id]
703
 
                    del inv[file_id]
704
 
        self._pb.clear()
 
718
                    if file_id is not None:
 
719
                        limbo_inv[trans_id] = inv[file_id]
 
720
                        del inv[file_id]
 
721
        finally:
 
722
            child_pb.finished()
705
723
 
706
724
    def _apply_insertions(self, inv, limbo_inv):
707
725
        """Perform tree operations that insert directory/inventory names.
711
729
        parent-to-child order.
712
730
        """
713
731
        new_paths = self.new_paths()
714
 
        for num, (path, trans_id) in enumerate(new_paths):
715
 
            self._pb.update('adding file', num+1, len(new_paths))
716
 
            try:
717
 
                kind = self._new_contents[trans_id]
718
 
            except KeyError:
719
 
                kind = contents = None
720
 
            if trans_id in self._new_contents or self.path_changed(trans_id):
721
 
                full_path = self._tree.abspath(path)
 
732
        modified_paths = []
 
733
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
 
734
        try:
 
735
            for num, (path, trans_id) in enumerate(new_paths):
 
736
                child_pb.update('adding file', num, len(new_paths))
722
737
                try:
723
 
                    os.rename(self._limbo_name(trans_id), full_path)
724
 
                except OSError, e:
725
 
                    # We may be renaming a dangling inventory id
726
 
                    if e.errno != errno.ENOENT:
727
 
                        raise
728
 
                if trans_id in self._new_contents:
729
 
                    del self._new_contents[trans_id]
730
 
 
731
 
            if trans_id in self._new_id:
732
 
                if kind is None:
733
 
                    kind = file_kind(self._tree.abspath(path))
734
 
                inv.add_path(path, kind, self._new_id[trans_id])
735
 
            elif trans_id in self._new_name or trans_id in self._new_parent:
736
 
                entry = limbo_inv.get(trans_id)
737
 
                if entry is not None:
738
 
                    entry.name = self.final_name(trans_id)
739
 
                    parent_path = os.path.dirname(path)
740
 
                    entry.parent_id = self._tree.inventory.path2id(parent_path)
741
 
                    inv.add(entry)
742
 
 
743
 
            # requires files and inventory entries to be in place
744
 
            if trans_id in self._new_executability:
745
 
                self._set_executability(path, inv, trans_id)
746
 
        self._pb.clear()
 
738
                    kind = self._new_contents[trans_id]
 
739
                except KeyError:
 
740
                    kind = contents = None
 
741
                if trans_id in self._new_contents or \
 
742
                    self.path_changed(trans_id):
 
743
                    full_path = self._tree.abspath(path)
 
744
                    try:
 
745
                        os.rename(self._limbo_name(trans_id), full_path)
 
746
                    except OSError, e:
 
747
                        # We may be renaming a dangling inventory id
 
748
                        if e.errno != errno.ENOENT:
 
749
                            raise
 
750
                    if trans_id in self._new_contents:
 
751
                        modified_paths.append(full_path)
 
752
                        del self._new_contents[trans_id]
 
753
 
 
754
                if trans_id in self._new_id:
 
755
                    if kind is None:
 
756
                        kind = file_kind(self._tree.abspath(path))
 
757
                    inv.add_path(path, kind, self._new_id[trans_id])
 
758
                elif trans_id in self._new_name or trans_id in\
 
759
                    self._new_parent:
 
760
                    entry = limbo_inv.get(trans_id)
 
761
                    if entry is not None:
 
762
                        entry.name = self.final_name(trans_id)
 
763
                        parent_path = os.path.dirname(path)
 
764
                        entry.parent_id = \
 
765
                            self._tree.inventory.path2id(parent_path)
 
766
                        inv.add(entry)
 
767
 
 
768
                # requires files and inventory entries to be in place
 
769
                if trans_id in self._new_executability:
 
770
                    self._set_executability(path, inv, trans_id)
 
771
        finally:
 
772
            child_pb.finished()
 
773
        return modified_paths
747
774
 
748
775
    def _set_executability(self, path, inv, trans_id):
749
776
        """Set the executability of versioned files """
1002
1029
 
1003
1030
    tt = TreeTransform(working_tree, pb)
1004
1031
    try:
 
1032
        merge_modified = working_tree.merge_modified()
1005
1033
        trans_id = {}
1006
1034
        def trans_id_file_id(file_id):
1007
1035
            try:
1009
1037
            except KeyError:
1010
1038
                return tt.trans_id_tree_file_id(file_id)
1011
1039
 
 
1040
        pp = ProgressPhase("Revert phase", 4, pb)
 
1041
        pp.next_phase()
1012
1042
        sorted_interesting = [i for i in topology_sorted_ids(target_tree) if
1013
1043
                              interesting(i)]
1014
 
        for id_num, file_id in enumerate(sorted_interesting):
1015
 
            pb.update("Reverting file", id_num+1, len(sorted_interesting))
1016
 
            if file_id not in working_tree.inventory:
1017
 
                entry = target_tree.inventory[file_id]
1018
 
                parent_id = trans_id_file_id(entry.parent_id)
1019
 
                e_trans_id = new_by_entry(tt, entry, parent_id, target_tree)
1020
 
                trans_id[file_id] = e_trans_id
1021
 
            else:
1022
 
                change_entry(tt, file_id, working_tree, target_tree, 
1023
 
                             trans_id_file_id, backups, trans_id)
 
1044
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
 
1045
        try:
 
1046
            for id_num, file_id in enumerate(sorted_interesting):
 
1047
                child_pb.update("Reverting file", id_num+1, 
 
1048
                                len(sorted_interesting))
 
1049
                if file_id not in working_tree.inventory:
 
1050
                    entry = target_tree.inventory[file_id]
 
1051
                    parent_id = trans_id_file_id(entry.parent_id)
 
1052
                    e_trans_id = new_by_entry(tt, entry, parent_id, target_tree)
 
1053
                    trans_id[file_id] = e_trans_id
 
1054
                else:
 
1055
                    backup_this = backups
 
1056
                    if file_id in merge_modified:
 
1057
                        backup_this = False
 
1058
                        del merge_modified[file_id]
 
1059
                    change_entry(tt, file_id, working_tree, target_tree, 
 
1060
                                 trans_id_file_id, backup_this, trans_id)
 
1061
        finally:
 
1062
            child_pb.finished()
 
1063
        pp.next_phase()
1024
1064
        wt_interesting = [i for i in working_tree.inventory if interesting(i)]
1025
 
        for id_num, file_id in enumerate(wt_interesting):
1026
 
            pb.update("New file check", id_num+1, len(sorted_interesting))
1027
 
            if file_id not in target_tree:
1028
 
                tt.unversion_file(tt.trans_id_tree_file_id(file_id))
1029
 
        raw_conflicts = resolve_conflicts(tt, pb)
 
1065
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
 
1066
        try:
 
1067
            for id_num, file_id in enumerate(wt_interesting):
 
1068
                child_pb.update("New file check", id_num+1, 
 
1069
                                len(sorted_interesting))
 
1070
                if file_id not in target_tree:
 
1071
                    trans_id = tt.trans_id_tree_file_id(file_id)
 
1072
                    tt.unversion_file(trans_id)
 
1073
                    if file_id in merge_modified:
 
1074
                        tt.delete_contents(trans_id)
 
1075
                        del merge_modified[file_id]
 
1076
        finally:
 
1077
            child_pb.finished()
 
1078
        pp.next_phase()
 
1079
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
 
1080
        try:
 
1081
            raw_conflicts = resolve_conflicts(tt, child_pb)
 
1082
        finally:
 
1083
            child_pb.finished()
1030
1084
        for line in conflicts_strings(cook_conflicts(raw_conflicts, tt)):
1031
1085
            warning(line)
 
1086
        pp.next_phase()
1032
1087
        tt.apply()
 
1088
        working_tree.set_merge_modified({})
1033
1089
    finally:
1034
1090
        tt.finalize()
1035
1091
        pb.clear()