/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] bzr.dev 2255

Show diffs side-by-side

added added

removed removed

Lines of Context:
73
73
 
74
74
from bzrlib import symbol_versioning
75
75
from bzrlib.decorators import needs_read_lock, needs_write_lock
76
 
from bzrlib.errors import (BzrCheckError,
77
 
                           BzrError,
78
 
                           ConflictFormatError,
79
 
                           WeaveRevisionNotPresent,
80
 
                           NotBranchError,
81
 
                           NoSuchFile,
82
 
                           NotVersionedError,
83
 
                           MergeModifiedFormatError,
84
 
                           UnsupportedOperation,
85
 
                           )
86
76
from bzrlib.inventory import InventoryEntry, Inventory, ROOT_ID
87
77
from bzrlib.lockable_files import LockableFiles, TransportLock
88
78
from bzrlib.lockdir import LockDir
92
82
    compact_date,
93
83
    file_kind,
94
84
    isdir,
 
85
    normpath,
95
86
    pathjoin,
 
87
    rand_chars,
 
88
    realpath,
96
89
    safe_unicode,
97
90
    splitpath,
98
 
    rand_chars,
99
 
    normpath,
100
 
    realpath,
101
91
    supports_executable,
102
92
    )
103
93
from bzrlib.trace import mutter, note
238
228
        mutter("opening working tree %r", basedir)
239
229
        if deprecated_passed(branch):
240
230
            if not _internal:
241
 
                warnings.warn("WorkingTree(..., branch=XXX) is deprecated as of bzr 0.8."
242
 
                     " Please use bzrdir.open_workingtree() or"
 
231
                warnings.warn("WorkingTree(..., branch=XXX) is deprecated"
 
232
                     " as of bzr 0.8. Please use bzrdir.open_workingtree() or"
243
233
                     " WorkingTree.open().",
244
234
                     DeprecationWarning,
245
235
                     stacklevel=2
264
254
        # if needed, or, when the cache sees a change, append it to the hash
265
255
        # cache file, and have the parser take the most recent entry for a
266
256
        # given path only.
267
 
        cache_filename = self.bzrdir.get_workingtree_transport(None).local_abspath('stat-cache')
 
257
        wt_trans = self.bzrdir.get_workingtree_transport(None)
 
258
        cache_filename = wt_trans.local_abspath('stat-cache')
268
259
        self._hashcache = hashcache.HashCache(basedir, cache_filename,
269
260
                                              self._control_files._file_mode)
270
261
        hc = self._hashcache
507
498
            parents = [last_rev]
508
499
        try:
509
500
            merges_file = self._control_files.get_utf8('pending-merges')
510
 
        except NoSuchFile:
 
501
        except errors.NoSuchFile:
511
502
            pass
512
503
        else:
513
504
            for l in merges_file.readlines():
626
617
                    kinds[pos] = file_kind(fullpath)
627
618
                except OSError, e:
628
619
                    if e.errno == errno.ENOENT:
629
 
                        raise NoSuchFile(fullpath)
 
620
                        raise errors.NoSuchFile(fullpath)
630
621
 
631
622
    @needs_write_lock
632
623
    def add_parent_tree_id(self, revision_id, allow_leftmost_as_ghost=False):
641
632
        :param allow_leftmost_as_ghost: Allow the first parent to be a ghost.
642
633
        """
643
634
        parents = self.get_parent_ids() + [revision_id]
644
 
        self.set_parent_ids(parents,
645
 
            allow_leftmost_as_ghost=len(parents) > 1 or allow_leftmost_as_ghost)
 
635
        self.set_parent_ids(parents, allow_leftmost_as_ghost=len(parents) > 1
 
636
            or allow_leftmost_as_ghost)
646
637
 
647
638
    @needs_tree_write_lock
648
639
    def add_parent_tree(self, parent_tuple, allow_leftmost_as_ghost=False):
782
773
        """Merge from a branch into this working tree.
783
774
 
784
775
        :param branch: The branch to merge from.
785
 
        :param to_revision: If non-None, the merge will merge to to_revision, but 
786
 
            not beyond it. to_revision does not need to be in the history of
787
 
            the branch when it is supplied. If None, to_revision defaults to
 
776
        :param to_revision: If non-None, the merge will merge to to_revision,
 
777
            but not beyond it. to_revision does not need to be in the history
 
778
            of the branch when it is supplied. If None, to_revision defaults to
788
779
            branch.last_revision().
789
780
        """
790
781
        from bzrlib.merge import Merger, Merge3Merger
824
815
    def merge_modified(self):
825
816
        try:
826
817
            hashfile = self._control_files.get('merge-hashes')
827
 
        except NoSuchFile:
 
818
        except errors.NoSuchFile:
828
819
            return {}
829
820
        merge_hashes = {}
830
821
        try:
831
822
            if hashfile.next() != MERGE_MODIFIED_HEADER_1 + '\n':
832
 
                raise MergeModifiedFormatError()
 
823
                raise errors.MergeModifiedFormatError()
833
824
        except StopIteration:
834
 
            raise MergeModifiedFormatError()
 
825
            raise errors.MergeModifiedFormatError()
835
826
        for s in RioReader(hashfile):
836
827
            file_id = s.get("file_id")
837
828
            if file_id not in self.inventory:
955
946
 
956
947
                if f_ie:
957
948
                    if f_ie.kind != fk:
958
 
                        raise BzrCheckError("file %r entered as kind %r id %r, "
959
 
                                            "now of kind %r"
960
 
                                            % (fap, f_ie.kind, f_ie.file_id, fk))
 
949
                        raise errors.BzrCheckError(
 
950
                            "file %r entered as kind %r id %r, now of kind %r"
 
951
                            % (fap, f_ie.kind, f_ie.file_id, fk))
961
952
 
962
953
                # make a last minute entry
963
954
                if f_ie:
977
968
                new_children.sort()
978
969
                new_children = collections.deque(new_children)
979
970
                stack.append((f_ie.file_id, fp, fap, new_children))
980
 
                # Break out of inner loop, so that we start outer loop with child
 
971
                # Break out of inner loop,
 
972
                # so that we start outer loop with child
981
973
                break
982
974
            else:
983
975
                # if we finished all children, pop it off the stack
984
976
                stack.pop()
985
977
 
986
978
    @needs_tree_write_lock
987
 
    def move(self, from_paths, to_name):
 
979
    def move(self, from_paths, to_dir=None, after=False, **kwargs):
988
980
        """Rename files.
989
981
 
990
 
        to_name must exist in the inventory.
 
982
        to_dir must exist in the inventory.
991
983
 
992
 
        If to_name exists and is a directory, the files are moved into
 
984
        If to_dir exists and is a directory, the files are moved into
993
985
        it, keeping their old names.  
994
986
 
995
 
        Note that to_name is only the last component of the new name;
 
987
        Note that to_dir is only the last component of the new name;
996
988
        this doesn't change the directory.
997
989
 
 
990
        For each entry in from_paths the move mode will be determined
 
991
        independently.
 
992
 
 
993
        The first mode moves the file in the filesystem and updates the
 
994
        inventory. The second mode only updates the inventory without
 
995
        touching the file on the filesystem. This is the new mode introduced
 
996
        in version 0.15.
 
997
 
 
998
        move uses the second mode if 'after == True' and the target is not
 
999
        versioned but present in the working tree.
 
1000
 
 
1001
        move uses the second mode if 'after == False' and the source is
 
1002
        versioned but no longer in the working tree, and the target is not
 
1003
        versioned but present in the working tree.
 
1004
 
 
1005
        move uses the first mode if 'after == False' and the source is
 
1006
        versioned and present in the working tree, and the target is not
 
1007
        versioned and not present in the working tree.
 
1008
 
 
1009
        Everything else results in an error.
 
1010
 
998
1011
        This returns a list of (from_path, to_path) pairs for each
999
1012
        entry that is moved.
1000
1013
        """
1001
 
        result = []
1002
 
        ## TODO: Option to move IDs only
 
1014
        rename_entries = []
 
1015
        rename_tuples = []
 
1016
 
 
1017
        # check for deprecated use of signature
 
1018
        if to_dir is None:
 
1019
            to_dir = kwargs.get('to_name', None)
 
1020
            if to_dir is None:
 
1021
                raise TypeError('You must supply a target directory')
 
1022
            else:
 
1023
                symbol_versioning.warn('The parameter to_name was deprecated'
 
1024
                                       ' in version 0.13. Use to_dir instead',
 
1025
                                       DeprecationWarning)
 
1026
 
 
1027
        # check destination directory
1003
1028
        assert not isinstance(from_paths, basestring)
1004
1029
        inv = self.inventory
1005
 
        to_abs = self.abspath(to_name)
 
1030
        to_abs = self.abspath(to_dir)
1006
1031
        if not isdir(to_abs):
1007
 
            raise BzrError("destination %r is not a directory" % to_abs)
1008
 
        if not self.has_filename(to_name):
1009
 
            raise BzrError("destination %r not in working directory" % to_abs)
1010
 
        to_dir_id = inv.path2id(to_name)
1011
 
        if to_dir_id is None and to_name != '':
1012
 
            raise BzrError("destination %r is not a versioned directory" % to_name)
 
1032
            raise errors.BzrMoveFailedError('',to_dir,
 
1033
                errors.NotADirectory(to_abs))
 
1034
        if not self.has_filename(to_dir):
 
1035
            raise errors.BzrMoveFailedError('',to_dir,
 
1036
                errors.NotInWorkingDirectory(to_dir))
 
1037
        to_dir_id = inv.path2id(to_dir)
 
1038
        if to_dir_id is None:
 
1039
            raise errors.BzrMoveFailedError('',to_dir,
 
1040
                errors.NotVersionedError(path=str(to_dir)))
 
1041
 
1013
1042
        to_dir_ie = inv[to_dir_id]
1014
1043
        if to_dir_ie.kind != 'directory':
1015
 
            raise BzrError("destination %r is not a directory" % to_abs)
1016
 
 
1017
 
        to_idpath = inv.get_idpath(to_dir_id)
1018
 
 
1019
 
        for f in from_paths:
1020
 
            if not self.has_filename(f):
1021
 
                raise BzrError("%r does not exist in working tree" % f)
1022
 
            f_id = inv.path2id(f)
1023
 
            if f_id is None:
1024
 
                raise BzrError("%r is not versioned" % f)
1025
 
            name_tail = splitpath(f)[-1]
1026
 
            dest_path = pathjoin(to_name, name_tail)
1027
 
            if self.has_filename(dest_path):
1028
 
                raise BzrError("destination %r already exists" % dest_path)
1029
 
            if f_id in to_idpath:
1030
 
                raise BzrError("can't move %r to a subdirectory of itself" % f)
1031
 
 
1032
 
        # OK, so there's a race here, it's possible that someone will
1033
 
        # create a file in this interval and then the rename might be
1034
 
        # left half-done.  But we should have caught most problems.
1035
 
        orig_inv = deepcopy(self.inventory)
 
1044
            raise errors.BzrMoveFailedError('',to_dir,
 
1045
                errors.NotADirectory(to_abs))
 
1046
 
 
1047
        # create rename entries and tuples
 
1048
        for from_rel in from_paths:
 
1049
            from_tail = splitpath(from_rel)[-1]
 
1050
            from_id = inv.path2id(from_rel)
 
1051
            if from_id is None:
 
1052
                raise errors.BzrMoveFailedError(from_rel,to_dir,
 
1053
                    errors.NotVersionedError(path=str(from_rel)))
 
1054
 
 
1055
            from_entry = inv[from_id]
 
1056
            from_parent_id = from_entry.parent_id
 
1057
            to_rel = pathjoin(to_dir, from_tail)
 
1058
            rename_entry = WorkingTree._RenameEntry(from_rel=from_rel,
 
1059
                                         from_id=from_id,
 
1060
                                         from_tail=from_tail,
 
1061
                                         from_parent_id=from_parent_id,
 
1062
                                         to_rel=to_rel, to_tail=from_tail,
 
1063
                                         to_parent_id=to_dir_id)
 
1064
            rename_entries.append(rename_entry)
 
1065
            rename_tuples.append((from_rel, to_rel))
 
1066
 
 
1067
        # determine which move mode to use. checks also for movability
 
1068
        rename_entries = self._determine_mv_mode(rename_entries, after)
 
1069
 
1036
1070
        original_modified = self._inventory_is_modified
1037
1071
        try:
1038
1072
            if len(from_paths):
1039
1073
                self._inventory_is_modified = True
1040
 
            for f in from_paths:
1041
 
                name_tail = splitpath(f)[-1]
1042
 
                dest_path = pathjoin(to_name, name_tail)
1043
 
                result.append((f, dest_path))
1044
 
                inv.rename(inv.path2id(f), to_dir_id, name_tail)
1045
 
                try:
1046
 
                    osutils.rename(self.abspath(f), self.abspath(dest_path))
1047
 
                except OSError, e:
1048
 
                    raise BzrError("failed to rename %r to %r: %s" %
1049
 
                                   (f, dest_path, e[1]))
 
1074
            self._move(rename_entries)
1050
1075
        except:
1051
1076
            # restore the inventory on error
1052
 
            self._set_inventory(orig_inv, dirty=original_modified)
 
1077
            self._inventory_is_modified = original_modified
1053
1078
            raise
1054
1079
        self._write_inventory(inv)
1055
 
        return result
 
1080
        return rename_tuples
 
1081
 
 
1082
    def _determine_mv_mode(self, rename_entries, after=False):
 
1083
        """Determines for each from-to pair if both inventory and working tree
 
1084
        or only the inventory has to be changed.
 
1085
 
 
1086
        Also does basic plausability tests.
 
1087
        """
 
1088
        inv = self.inventory
 
1089
 
 
1090
        for rename_entry in rename_entries:
 
1091
            # store to local variables for easier reference
 
1092
            from_rel = rename_entry.from_rel
 
1093
            from_id = rename_entry.from_id
 
1094
            to_rel = rename_entry.to_rel
 
1095
            to_id = inv.path2id(to_rel)
 
1096
            only_change_inv = False
 
1097
 
 
1098
            # check the inventory for source and destination
 
1099
            if from_id is None:
 
1100
                raise errors.BzrMoveFailedError(from_rel,to_rel,
 
1101
                    errors.NotVersionedError(path=str(from_rel)))
 
1102
            if to_id is not None:
 
1103
                raise errors.BzrMoveFailedError(from_rel,to_rel,
 
1104
                    errors.AlreadyVersionedError(path=str(to_rel)))
 
1105
 
 
1106
            # try to determine the mode for rename (only change inv or change
 
1107
            # inv and file system)
 
1108
            if after:
 
1109
                if not self.has_filename(to_rel):
 
1110
                    raise errors.BzrMoveFailedError(from_id,to_rel,
 
1111
                        errors.NoSuchFile(path=str(to_rel),
 
1112
                        extra="New file has not been created yet"))
 
1113
                only_change_inv = True
 
1114
            elif not self.has_filename(from_rel) and self.has_filename(to_rel):
 
1115
                only_change_inv = True
 
1116
            elif self.has_filename(from_rel) and not self.has_filename(to_rel):
 
1117
                only_change_inv = False
 
1118
            else:
 
1119
                # something is wrong, so lets determine what exactly
 
1120
                if not self.has_filename(from_rel) and \
 
1121
                   not self.has_filename(to_rel):
 
1122
                    raise errors.BzrRenameFailedError(from_rel,to_rel,
 
1123
                        errors.PathsDoNotExist(paths=(str(from_rel),
 
1124
                        str(to_rel))))
 
1125
                else:
 
1126
                    raise errors.RenameFailedFilesExist(from_rel, to_rel,
 
1127
                        extra="(Use --after to update the Bazaar id)")
 
1128
            rename_entry.only_change_inv = only_change_inv
 
1129
        return rename_entries
 
1130
 
 
1131
    def _move(self, rename_entries):
 
1132
        """Moves a list of files.
 
1133
 
 
1134
        Depending on the value of the flag 'only_change_inv', the
 
1135
        file will be moved on the file system or not.
 
1136
        """
 
1137
        inv = self.inventory
 
1138
        moved = []
 
1139
 
 
1140
        for entry in rename_entries:
 
1141
            try:
 
1142
                self._move_entry(entry)
 
1143
            except:
 
1144
                self._rollback_move(moved)
 
1145
                raise
 
1146
            moved.append(entry)
 
1147
 
 
1148
    def _rollback_move(self, moved):
 
1149
        """Try to rollback a previous move in case of an filesystem error."""
 
1150
        inv = self.inventory
 
1151
        for entry in moved:
 
1152
            try:
 
1153
                self._move_entry(_RenameEntry(entry.to_rel, entry.from_id,
 
1154
                    entry.to_tail, entry.to_parent_id, entry.from_rel,
 
1155
                    entry.from_tail, entry.from_parent_id,
 
1156
                    entry.only_change_inv))
 
1157
            except errors.BzrMoveFailedError, e:
 
1158
                raise errors.BzrMoveFailedError( '', '', "Rollback failed."
 
1159
                        " The working tree is in an inconsistent state."
 
1160
                        " Please consider doing a 'bzr revert'."
 
1161
                        " Error message is: %s" % e)
 
1162
 
 
1163
    def _move_entry(self, entry):
 
1164
        inv = self.inventory
 
1165
        from_rel_abs = self.abspath(entry.from_rel)
 
1166
        to_rel_abs = self.abspath(entry.to_rel)
 
1167
        if from_rel_abs == to_rel_abs:
 
1168
            raise errors.BzrMoveFailedError(entry.from_rel, entry.to_rel,
 
1169
                "Source and target are identical.")
 
1170
 
 
1171
        if not entry.only_change_inv:
 
1172
            try:
 
1173
                osutils.rename(from_rel_abs, to_rel_abs)
 
1174
            except OSError, e:
 
1175
                raise errors.BzrMoveFailedError(entry.from_rel,
 
1176
                    entry.to_rel, e[1])
 
1177
        inv.rename(entry.from_id, entry.to_parent_id, entry.to_tail)
1056
1178
 
1057
1179
    @needs_tree_write_lock
1058
 
    def rename_one(self, from_rel, to_rel):
 
1180
    def rename_one(self, from_rel, to_rel, after=False):
1059
1181
        """Rename one file.
1060
1182
 
1061
1183
        This can change the directory or the filename or both.
 
1184
 
 
1185
        rename_one has several 'modes' to work. First, it can rename a physical
 
1186
        file and change the file_id. That is the normal mode. Second, it can
 
1187
        only change the file_id without touching any physical file. This is
 
1188
        the new mode introduced in version 0.15.
 
1189
 
 
1190
        rename_one uses the second mode if 'after == True' and 'to_rel' is not
 
1191
        versioned but present in the working tree.
 
1192
 
 
1193
        rename_one uses the second mode if 'after == False' and 'from_rel' is
 
1194
        versioned but no longer in the working tree, and 'to_rel' is not
 
1195
        versioned but present in the working tree.
 
1196
 
 
1197
        rename_one uses the first mode if 'after == False' and 'from_rel' is
 
1198
        versioned and present in the working tree, and 'to_rel' is not
 
1199
        versioned and not present in the working tree.
 
1200
 
 
1201
        Everything else results in an error.
1062
1202
        """
1063
1203
        inv = self.inventory
1064
 
        if not self.has_filename(from_rel):
1065
 
            raise BzrError("can't rename: old working file %r does not exist" % from_rel)
1066
 
        if self.has_filename(to_rel):
1067
 
            raise BzrError("can't rename: new working file %r already exists" % to_rel)
1068
 
 
1069
 
        file_id = inv.path2id(from_rel)
1070
 
        if file_id is None:
1071
 
            raise BzrError("can't rename: old name %r is not versioned" % from_rel)
1072
 
 
1073
 
        entry = inv[file_id]
1074
 
        from_parent = entry.parent_id
1075
 
        from_name = entry.name
1076
 
        
1077
 
        if inv.path2id(to_rel):
1078
 
            raise BzrError("can't rename: new name %r is already versioned" % to_rel)
1079
 
 
 
1204
        rename_entries = []
 
1205
 
 
1206
        # create rename entries and tuples
 
1207
        from_tail = splitpath(from_rel)[-1]
 
1208
        from_id = inv.path2id(from_rel)
 
1209
        if from_id is None:
 
1210
            raise errors.BzrRenameFailedError(from_rel,to_rel,
 
1211
                errors.NotVersionedError(path=str(from_rel)))
 
1212
        from_entry = inv[from_id]
 
1213
        from_parent_id = from_entry.parent_id
1080
1214
        to_dir, to_tail = os.path.split(to_rel)
1081
1215
        to_dir_id = inv.path2id(to_dir)
1082
 
        if to_dir_id is None and to_dir != '':
1083
 
            raise BzrError("can't determine destination directory id for %r" % to_dir)
1084
 
 
1085
 
        mutter("rename_one:")
1086
 
        mutter("  file_id    {%s}" % file_id)
1087
 
        mutter("  from_rel   %r" % from_rel)
1088
 
        mutter("  to_rel     %r" % to_rel)
1089
 
        mutter("  to_dir     %r" % to_dir)
1090
 
        mutter("  to_dir_id  {%s}" % to_dir_id)
1091
 
 
1092
 
        inv.rename(file_id, to_dir_id, to_tail)
1093
 
 
1094
 
        from_abs = self.abspath(from_rel)
1095
 
        to_abs = self.abspath(to_rel)
1096
 
        try:
1097
 
            osutils.rename(from_abs, to_abs)
1098
 
        except OSError, e:
1099
 
            inv.rename(file_id, from_parent, from_name)
1100
 
            raise BzrError("failed to rename %r to %r: %s"
1101
 
                    % (from_abs, to_abs, e[1]))
 
1216
        rename_entry = WorkingTree._RenameEntry(from_rel=from_rel,
 
1217
                                     from_id=from_id,
 
1218
                                     from_tail=from_tail,
 
1219
                                     from_parent_id=from_parent_id,
 
1220
                                     to_rel=to_rel, to_tail=to_tail,
 
1221
                                     to_parent_id=to_dir_id)
 
1222
        rename_entries.append(rename_entry)
 
1223
 
 
1224
        # determine which move mode to use. checks also for movability
 
1225
        rename_entries = self._determine_mv_mode(rename_entries, after)
 
1226
 
 
1227
        # check if the target changed directory and if the target directory is
 
1228
        # versioned
 
1229
        if to_dir_id is None:
 
1230
            raise errors.BzrMoveFailedError(from_rel,to_rel,
 
1231
                errors.NotVersionedError(path=str(to_dir)))
 
1232
 
 
1233
        # all checks done. now we can continue with our actual work
 
1234
        mutter('rename_one:\n'
 
1235
               '  from_id   {%s}\n'
 
1236
               '  from_rel: %r\n'
 
1237
               '  to_rel:   %r\n'
 
1238
               '  to_dir    %r\n'
 
1239
               '  to_dir_id {%s}\n',
 
1240
               from_id, from_rel, to_rel, to_dir, to_dir_id)
 
1241
 
 
1242
        self._move(rename_entries)
1102
1243
        self._write_inventory(inv)
1103
1244
 
 
1245
    class _RenameEntry(object):
 
1246
        def __init__(self, from_rel, from_id, from_tail, from_parent_id,
 
1247
                     to_rel, to_tail, to_parent_id, only_change_inv=False):
 
1248
            self.from_rel = from_rel
 
1249
            self.from_id = from_id
 
1250
            self.from_tail = from_tail
 
1251
            self.from_parent_id = from_parent_id
 
1252
            self.to_rel = to_rel
 
1253
            self.to_tail = to_tail
 
1254
            self.to_parent_id = to_parent_id
 
1255
            self.only_change_inv = only_change_inv
 
1256
 
1104
1257
    @needs_read_lock
1105
1258
    def unknowns(self):
1106
1259
        """Return all unknown files.
1484
1637
            if not fid:
1485
1638
                # TODO: Perhaps make this just a warning, and continue?
1486
1639
                # This tends to happen when 
1487
 
                raise NotVersionedError(path=f)
 
1640
                raise errors.NotVersionedError(path=f)
1488
1641
            if verbose:
1489
1642
                # having remove it, it must be either ignored or unknown
1490
1643
                if self.is_ignored(f):
1499
1652
 
1500
1653
    @needs_tree_write_lock
1501
1654
    def revert(self, filenames, old_tree=None, backups=True, 
1502
 
               pb=DummyProgress()):
 
1655
               pb=DummyProgress(), report_changes=False):
1503
1656
        from bzrlib.conflicts import resolve
1504
1657
        if old_tree is None:
1505
1658
            old_tree = self.basis_tree()
1506
 
        conflicts = transform.revert(self, old_tree, filenames, backups, pb)
 
1659
        conflicts = transform.revert(self, old_tree, filenames, backups, pb,
 
1660
                                     report_changes)
1507
1661
        if not len(filenames):
1508
1662
            self.set_parent_ids(self.get_parent_ids()[:1])
1509
1663
            resolve(self)
1557
1711
            elif kind == 'symlink':
1558
1712
                inv.add(InventoryLink(file_id, name, parent))
1559
1713
            else:
1560
 
                raise BzrError("unknown kind %r" % kind)
 
1714
                raise errors.BzrError("unknown kind %r" % kind)
1561
1715
        self._write_inventory(inv)
1562
1716
 
1563
1717
    @needs_tree_write_lock
1738
1892
        self.flush()
1739
1893
 
1740
1894
    def set_conflicts(self, arg):
1741
 
        raise UnsupportedOperation(self.set_conflicts, self)
 
1895
        raise errors.UnsupportedOperation(self.set_conflicts, self)
1742
1896
 
1743
1897
    def add_conflicts(self, arg):
1744
 
        raise UnsupportedOperation(self.add_conflicts, self)
 
1898
        raise errors.UnsupportedOperation(self.add_conflicts, self)
1745
1899
 
1746
1900
    @needs_read_lock
1747
1901
    def conflicts(self):
1821
1975
        """See Mutable.last_revision."""
1822
1976
        try:
1823
1977
            return self._control_files.get_utf8('last-revision').read()
1824
 
        except NoSuchFile:
 
1978
        except errors.NoSuchFile:
1825
1979
            return None
1826
1980
 
1827
1981
    def _change_last_revision(self, revision_id):
1852
2006
    def conflicts(self):
1853
2007
        try:
1854
2008
            confile = self._control_files.get('conflicts')
1855
 
        except NoSuchFile:
 
2009
        except errors.NoSuchFile:
1856
2010
            return _mod_conflicts.ConflictList()
1857
2011
        try:
1858
2012
            if confile.next() != CONFLICT_HEADER_1 + '\n':
1859
 
                raise ConflictFormatError()
 
2013
                raise errors.ConflictFormatError()
1860
2014
        except StopIteration:
1861
 
            raise ConflictFormatError()
 
2015
            raise errors.ConflictFormatError()
1862
2016
        return _mod_conflicts.ConflictList.from_stanzas(RioReader(confile))
1863
2017
 
1864
2018
    def unlock(self):
1926
2080
            transport = a_bzrdir.get_workingtree_transport(None)
1927
2081
            format_string = transport.get("format").read()
1928
2082
            return klass._formats[format_string]
1929
 
        except NoSuchFile:
 
2083
        except errors.NoSuchFile:
1930
2084
            raise errors.NoWorkingTree(base=transport.base)
1931
2085
        except KeyError:
1932
2086
            raise errors.UnknownFormatError(format=format_string)