~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: John Arbash Meinel
  • Date: 2007-01-24 20:40:20 UTC
  • mfrom: (2242 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2245.
  • Revision ID: john@arbash-meinel.com-20070124204020-szyxbjpn9mzbsks7
[merge] bzr.dev 2242

Show diffs side-by-side

added added

removed removed

Lines of Context:
72
72
 
73
73
from bzrlib import symbol_versioning
74
74
from bzrlib.decorators import needs_read_lock, needs_write_lock
75
 
from bzrlib.errors import (BzrCheckError,
76
 
                           BzrError,
77
 
                           ConflictFormatError,
78
 
                           WeaveRevisionNotPresent,
79
 
                           NotBranchError,
80
 
                           NoSuchFile,
81
 
                           NotVersionedError,
82
 
                           MergeModifiedFormatError,
83
 
                           UnsupportedOperation,
84
 
                           )
85
75
from bzrlib.inventory import InventoryEntry, Inventory, ROOT_ID
86
76
from bzrlib.lockable_files import LockableFiles, TransportLock
87
77
from bzrlib.lockdir import LockDir
91
81
    compact_date,
92
82
    file_kind,
93
83
    isdir,
 
84
    normpath,
94
85
    pathjoin,
 
86
    rand_chars,
 
87
    realpath,
95
88
    safe_unicode,
96
89
    splitpath,
97
 
    rand_chars,
98
 
    normpath,
99
 
    realpath,
100
90
    supports_executable,
101
91
    )
102
92
from bzrlib.trace import mutter, note
239
229
        mutter("opening working tree %r", basedir)
240
230
        if deprecated_passed(branch):
241
231
            if not _internal:
242
 
                warnings.warn("WorkingTree(..., branch=XXX) is deprecated as of bzr 0.8."
243
 
                     " Please use bzrdir.open_workingtree() or"
 
232
                warnings.warn("WorkingTree(..., branch=XXX) is deprecated"
 
233
                     " as of bzr 0.8. Please use bzrdir.open_workingtree() or"
244
234
                     " WorkingTree.open().",
245
235
                     DeprecationWarning,
246
236
                     stacklevel=2
265
255
        # if needed, or, when the cache sees a change, append it to the hash
266
256
        # cache file, and have the parser take the most recent entry for a
267
257
        # given path only.
268
 
        cache_filename = self.bzrdir.get_workingtree_transport(None).local_abspath('stat-cache')
 
258
        wt_trans = self.bzrdir.get_workingtree_transport(None)
 
259
        cache_filename = wt_trans.local_abspath('stat-cache')
269
260
        self._hashcache = hashcache.HashCache(basedir, cache_filename,
270
261
                                              self._control_files._file_mode)
271
262
        hc = self._hashcache
395
386
                if inv is not None and inv.revision_id == revision_id:
396
387
                    return bzrlib.revisiontree.RevisionTree(
397
388
                        self.branch.repository, inv, revision_id)
398
 
            except (NoSuchFile, errors.BadInventoryFormat):
 
389
            except (errors.NoSuchFile, errors.BadInventoryFormat):
399
390
                pass
400
391
        # No cached copy available, retrieve from the repository.
401
392
        # FIXME? RBC 20060403 should we cache the inventory locally
513
504
            parents = [last_rev]
514
505
        try:
515
506
            merges_file = self._control_files.get_utf8('pending-merges')
516
 
        except NoSuchFile:
 
507
        except errors.NoSuchFile:
517
508
            pass
518
509
        else:
519
510
            for l in merges_file.readlines():
632
623
                    kinds[pos] = file_kind(fullpath)
633
624
                except OSError, e:
634
625
                    if e.errno == errno.ENOENT:
635
 
                        raise NoSuchFile(fullpath)
 
626
                        raise errors.NoSuchFile(fullpath)
636
627
 
637
628
    @needs_write_lock
638
629
    def add_parent_tree_id(self, revision_id, allow_leftmost_as_ghost=False):
647
638
        :param allow_leftmost_as_ghost: Allow the first parent to be a ghost.
648
639
        """
649
640
        parents = self.get_parent_ids() + [revision_id]
650
 
        self.set_parent_ids(parents,
651
 
            allow_leftmost_as_ghost=len(parents) > 1 or allow_leftmost_as_ghost)
 
641
        self.set_parent_ids(parents, allow_leftmost_as_ghost=len(parents) > 1
 
642
            or allow_leftmost_as_ghost)
652
643
 
653
644
    @needs_tree_write_lock
654
645
    def add_parent_tree(self, parent_tuple, allow_leftmost_as_ghost=False):
788
779
        """Merge from a branch into this working tree.
789
780
 
790
781
        :param branch: The branch to merge from.
791
 
        :param to_revision: If non-None, the merge will merge to to_revision, but 
792
 
            not beyond it. to_revision does not need to be in the history of
793
 
            the branch when it is supplied. If None, to_revision defaults to
 
782
        :param to_revision: If non-None, the merge will merge to to_revision,
 
783
            but not beyond it. to_revision does not need to be in the history
 
784
            of the branch when it is supplied. If None, to_revision defaults to
794
785
            branch.last_revision().
795
786
        """
796
787
        from bzrlib.merge import Merger, Merge3Merger
830
821
    def merge_modified(self):
831
822
        try:
832
823
            hashfile = self._control_files.get('merge-hashes')
833
 
        except NoSuchFile:
 
824
        except errors.NoSuchFile:
834
825
            return {}
835
826
        merge_hashes = {}
836
827
        try:
837
828
            if hashfile.next() != MERGE_MODIFIED_HEADER_1 + '\n':
838
 
                raise MergeModifiedFormatError()
 
829
                raise errors.MergeModifiedFormatError()
839
830
        except StopIteration:
840
 
            raise MergeModifiedFormatError()
 
831
            raise errors.MergeModifiedFormatError()
841
832
        for s in RioReader(hashfile):
842
833
            file_id = s.get("file_id")
843
834
            if file_id not in self.inventory:
961
952
 
962
953
                if f_ie:
963
954
                    if f_ie.kind != fk:
964
 
                        raise BzrCheckError("file %r entered as kind %r id %r, "
965
 
                                            "now of kind %r"
966
 
                                            % (fap, f_ie.kind, f_ie.file_id, fk))
 
955
                        raise errors.BzrCheckError(
 
956
                            "file %r entered as kind %r id %r, now of kind %r"
 
957
                            % (fap, f_ie.kind, f_ie.file_id, fk))
967
958
 
968
959
                # make a last minute entry
969
960
                if f_ie:
983
974
                new_children.sort()
984
975
                new_children = collections.deque(new_children)
985
976
                stack.append((f_ie.file_id, fp, fap, new_children))
986
 
                # Break out of inner loop, so that we start outer loop with child
 
977
                # Break out of inner loop,
 
978
                # so that we start outer loop with child
987
979
                break
988
980
            else:
989
981
                # if we finished all children, pop it off the stack
990
982
                stack.pop()
991
983
 
992
984
    @needs_tree_write_lock
993
 
    def move(self, from_paths, to_name):
 
985
    def move(self, from_paths, to_dir=None, after=False, **kwargs):
994
986
        """Rename files.
995
987
 
996
 
        to_name must exist in the inventory.
 
988
        to_dir must exist in the inventory.
997
989
 
998
 
        If to_name exists and is a directory, the files are moved into
 
990
        If to_dir exists and is a directory, the files are moved into
999
991
        it, keeping their old names.  
1000
992
 
1001
 
        Note that to_name is only the last component of the new name;
 
993
        Note that to_dir is only the last component of the new name;
1002
994
        this doesn't change the directory.
1003
995
 
 
996
        For each entry in from_paths the move mode will be determined
 
997
        independently.
 
998
 
 
999
        The first mode moves the file in the filesystem and updates the
 
1000
        inventory. The second mode only updates the inventory without
 
1001
        touching the file on the filesystem. This is the new mode introduced
 
1002
        in version 0.15.
 
1003
 
 
1004
        move uses the second mode if 'after == True' and the target is not
 
1005
        versioned but present in the working tree.
 
1006
 
 
1007
        move uses the second mode if 'after == False' and the source is
 
1008
        versioned but no longer in the working tree, and the target is not
 
1009
        versioned but present in the working tree.
 
1010
 
 
1011
        move uses the first mode if 'after == False' and the source is
 
1012
        versioned and present in the working tree, and the target is not
 
1013
        versioned and not present in the working tree.
 
1014
 
 
1015
        Everything else results in an error.
 
1016
 
1004
1017
        This returns a list of (from_path, to_path) pairs for each
1005
1018
        entry that is moved.
1006
1019
        """
1007
 
        result = []
1008
 
        ## TODO: Option to move IDs only
 
1020
        rename_entries = []
 
1021
        rename_tuples = []
 
1022
 
 
1023
        # check for deprecated use of signature
 
1024
        if to_dir is None:
 
1025
            to_dir = kwargs.get('to_name', None)
 
1026
            if to_dir is None:
 
1027
                raise TypeError('You must supply a target directory')
 
1028
            else:
 
1029
                symbol_versioning.warn('The parameter to_name was deprecated'
 
1030
                                       ' in version 0.13. Use to_dir instead',
 
1031
                                       DeprecationWarning)
 
1032
 
 
1033
        # check destination directory
1009
1034
        assert not isinstance(from_paths, basestring)
1010
1035
        inv = self.inventory
1011
 
        to_abs = self.abspath(to_name)
 
1036
        to_abs = self.abspath(to_dir)
1012
1037
        if not isdir(to_abs):
1013
 
            raise BzrError("destination %r is not a directory" % to_abs)
1014
 
        if not self.has_filename(to_name):
1015
 
            raise BzrError("destination %r not in working directory" % to_abs)
1016
 
        to_dir_id = inv.path2id(to_name)
1017
 
        if to_dir_id is None and to_name != '':
1018
 
            raise BzrError("destination %r is not a versioned directory" % to_name)
 
1038
            raise errors.BzrMoveFailedError('',to_dir,
 
1039
                errors.NotADirectory(to_abs))
 
1040
        if not self.has_filename(to_dir):
 
1041
            raise errors.BzrMoveFailedError('',to_dir,
 
1042
                errors.NotInWorkingDirectory(to_dir))
 
1043
        to_dir_id = inv.path2id(to_dir)
 
1044
        if to_dir_id is None:
 
1045
            raise errors.BzrMoveFailedError('',to_dir,
 
1046
                errors.NotVersionedError(path=str(to_dir)))
 
1047
 
1019
1048
        to_dir_ie = inv[to_dir_id]
1020
1049
        if to_dir_ie.kind != 'directory':
1021
 
            raise BzrError("destination %r is not a directory" % to_abs)
1022
 
 
1023
 
        to_idpath = inv.get_idpath(to_dir_id)
1024
 
 
1025
 
        for f in from_paths:
1026
 
            if not self.has_filename(f):
1027
 
                raise BzrError("%r does not exist in working tree" % f)
1028
 
            f_id = inv.path2id(f)
1029
 
            if f_id is None:
1030
 
                raise BzrError("%r is not versioned" % f)
1031
 
            name_tail = splitpath(f)[-1]
1032
 
            dest_path = pathjoin(to_name, name_tail)
1033
 
            if self.has_filename(dest_path):
1034
 
                raise BzrError("destination %r already exists" % dest_path)
1035
 
            if f_id in to_idpath:
1036
 
                raise BzrError("can't move %r to a subdirectory of itself" % f)
1037
 
 
1038
 
        # OK, so there's a race here, it's possible that someone will
1039
 
        # create a file in this interval and then the rename might be
1040
 
        # left half-done.  But we should have caught most problems.
1041
 
        orig_inv = deepcopy(self.inventory)
 
1050
            raise errors.BzrMoveFailedError('',to_dir,
 
1051
                errors.NotADirectory(to_abs))
 
1052
 
 
1053
        # create rename entries and tuples
 
1054
        for from_rel in from_paths:
 
1055
            from_tail = splitpath(from_rel)[-1]
 
1056
            from_id = inv.path2id(from_rel)
 
1057
            if from_id is None:
 
1058
                raise errors.BzrMoveFailedError(from_rel,to_dir,
 
1059
                    errors.NotVersionedError(path=str(from_rel)))
 
1060
 
 
1061
            from_entry = inv[from_id]
 
1062
            from_parent_id = from_entry.parent_id
 
1063
            to_rel = pathjoin(to_dir, from_tail)
 
1064
            rename_entry = WorkingTree._RenameEntry(from_rel=from_rel,
 
1065
                                         from_id=from_id,
 
1066
                                         from_tail=from_tail,
 
1067
                                         from_parent_id=from_parent_id,
 
1068
                                         to_rel=to_rel, to_tail=from_tail,
 
1069
                                         to_parent_id=to_dir_id)
 
1070
            rename_entries.append(rename_entry)
 
1071
            rename_tuples.append((from_rel, to_rel))
 
1072
 
 
1073
        # determine which move mode to use. checks also for movability
 
1074
        rename_entries = self._determine_mv_mode(rename_entries, after)
 
1075
 
1042
1076
        original_modified = self._inventory_is_modified
1043
1077
        try:
1044
1078
            if len(from_paths):
1045
1079
                self._inventory_is_modified = True
1046
 
            for f in from_paths:
1047
 
                name_tail = splitpath(f)[-1]
1048
 
                dest_path = pathjoin(to_name, name_tail)
1049
 
                result.append((f, dest_path))
1050
 
                inv.rename(inv.path2id(f), to_dir_id, name_tail)
1051
 
                try:
1052
 
                    osutils.rename(self.abspath(f), self.abspath(dest_path))
1053
 
                except OSError, e:
1054
 
                    raise BzrError("failed to rename %r to %r: %s" %
1055
 
                                   (f, dest_path, e[1]))
 
1080
            self._move(rename_entries)
1056
1081
        except:
1057
1082
            # restore the inventory on error
1058
 
            self._set_inventory(orig_inv, dirty=original_modified)
 
1083
            self._inventory_is_modified = original_modified
1059
1084
            raise
1060
1085
        self._write_inventory(inv)
1061
 
        return result
 
1086
        return rename_tuples
 
1087
 
 
1088
    def _determine_mv_mode(self, rename_entries, after=False):
 
1089
        """Determines for each from-to pair if both inventory and working tree
 
1090
        or only the inventory has to be changed.
 
1091
 
 
1092
        Also does basic plausability tests.
 
1093
        """
 
1094
        inv = self.inventory
 
1095
 
 
1096
        for rename_entry in rename_entries:
 
1097
            # store to local variables for easier reference
 
1098
            from_rel = rename_entry.from_rel
 
1099
            from_id = rename_entry.from_id
 
1100
            to_rel = rename_entry.to_rel
 
1101
            to_id = inv.path2id(to_rel)
 
1102
            only_change_inv = False
 
1103
 
 
1104
            # check the inventory for source and destination
 
1105
            if from_id is None:
 
1106
                raise errors.BzrMoveFailedError(from_rel,to_rel,
 
1107
                    errors.NotVersionedError(path=str(from_rel)))
 
1108
            if to_id is not None:
 
1109
                raise errors.BzrMoveFailedError(from_rel,to_rel,
 
1110
                    errors.AlreadyVersionedError(path=str(to_rel)))
 
1111
 
 
1112
            # try to determine the mode for rename (only change inv or change
 
1113
            # inv and file system)
 
1114
            if after:
 
1115
                if not self.has_filename(to_rel):
 
1116
                    raise errors.BzrMoveFailedError(from_id,to_rel,
 
1117
                        errors.NoSuchFile(path=str(to_rel),
 
1118
                        extra="New file has not been created yet"))
 
1119
                only_change_inv = True
 
1120
            elif not self.has_filename(from_rel) and self.has_filename(to_rel):
 
1121
                only_change_inv = True
 
1122
            elif self.has_filename(from_rel) and not self.has_filename(to_rel):
 
1123
                only_change_inv = False
 
1124
            else:
 
1125
                # something is wrong, so lets determine what exactly
 
1126
                if not self.has_filename(from_rel) and \
 
1127
                   not self.has_filename(to_rel):
 
1128
                    raise errors.BzrRenameFailedError(from_rel,to_rel,
 
1129
                        errors.PathsDoNotExist(paths=(str(from_rel),
 
1130
                        str(to_rel))))
 
1131
                else:
 
1132
                    raise errors.RenameFailedFilesExist(from_rel, to_rel,
 
1133
                        extra="(Use --after to update the Bazaar id)")
 
1134
            rename_entry.only_change_inv = only_change_inv
 
1135
        return rename_entries
 
1136
 
 
1137
    def _move(self, rename_entries):
 
1138
        """Moves a list of files.
 
1139
 
 
1140
        Depending on the value of the flag 'only_change_inv', the
 
1141
        file will be moved on the file system or not.
 
1142
        """
 
1143
        inv = self.inventory
 
1144
        moved = []
 
1145
 
 
1146
        for entry in rename_entries:
 
1147
            try:
 
1148
                self._move_entry(entry)
 
1149
            except:
 
1150
                self._rollback_move(moved)
 
1151
                raise
 
1152
            moved.append(entry)
 
1153
 
 
1154
    def _rollback_move(self, moved):
 
1155
        """Try to rollback a previous move in case of an filesystem error."""
 
1156
        inv = self.inventory
 
1157
        for entry in moved:
 
1158
            try:
 
1159
                self._move_entry(_RenameEntry(entry.to_rel, entry.from_id,
 
1160
                    entry.to_tail, entry.to_parent_id, entry.from_rel,
 
1161
                    entry.from_tail, entry.from_parent_id,
 
1162
                    entry.only_change_inv))
 
1163
            except errors.BzrMoveFailedError, e:
 
1164
                raise errors.BzrMoveFailedError( '', '', "Rollback failed."
 
1165
                        " The working tree is in an inconsistent state."
 
1166
                        " Please consider doing a 'bzr revert'."
 
1167
                        " Error message is: %s" % e)
 
1168
 
 
1169
    def _move_entry(self, entry):
 
1170
        inv = self.inventory
 
1171
        from_rel_abs = self.abspath(entry.from_rel)
 
1172
        to_rel_abs = self.abspath(entry.to_rel)
 
1173
        if from_rel_abs == to_rel_abs:
 
1174
            raise errors.BzrMoveFailedError(entry.from_rel, entry.to_rel,
 
1175
                "Source and target are identical.")
 
1176
 
 
1177
        if not entry.only_change_inv:
 
1178
            try:
 
1179
                osutils.rename(from_rel_abs, to_rel_abs)
 
1180
            except OSError, e:
 
1181
                raise errors.BzrMoveFailedError(entry.from_rel,
 
1182
                    entry.to_rel, e[1])
 
1183
        inv.rename(entry.from_id, entry.to_parent_id, entry.to_tail)
1062
1184
 
1063
1185
    @needs_tree_write_lock
1064
 
    def rename_one(self, from_rel, to_rel):
 
1186
    def rename_one(self, from_rel, to_rel, after=False):
1065
1187
        """Rename one file.
1066
1188
 
1067
1189
        This can change the directory or the filename or both.
 
1190
 
 
1191
        rename_one has several 'modes' to work. First, it can rename a physical
 
1192
        file and change the file_id. That is the normal mode. Second, it can
 
1193
        only change the file_id without touching any physical file. This is
 
1194
        the new mode introduced in version 0.15.
 
1195
 
 
1196
        rename_one uses the second mode if 'after == True' and 'to_rel' is not
 
1197
        versioned but present in the working tree.
 
1198
 
 
1199
        rename_one uses the second mode if 'after == False' and 'from_rel' is
 
1200
        versioned but no longer in the working tree, and 'to_rel' is not
 
1201
        versioned but present in the working tree.
 
1202
 
 
1203
        rename_one uses the first mode if 'after == False' and 'from_rel' is
 
1204
        versioned and present in the working tree, and 'to_rel' is not
 
1205
        versioned and not present in the working tree.
 
1206
 
 
1207
        Everything else results in an error.
1068
1208
        """
1069
1209
        inv = self.inventory
1070
 
        if not self.has_filename(from_rel):
1071
 
            raise BzrError("can't rename: old working file %r does not exist" % from_rel)
1072
 
        if self.has_filename(to_rel):
1073
 
            raise BzrError("can't rename: new working file %r already exists" % to_rel)
1074
 
 
1075
 
        file_id = inv.path2id(from_rel)
1076
 
        if file_id is None:
1077
 
            raise BzrError("can't rename: old name %r is not versioned" % from_rel)
1078
 
 
1079
 
        entry = inv[file_id]
1080
 
        from_parent = entry.parent_id
1081
 
        from_name = entry.name
1082
 
        
1083
 
        if inv.path2id(to_rel):
1084
 
            raise BzrError("can't rename: new name %r is already versioned" % to_rel)
1085
 
 
 
1210
        rename_entries = []
 
1211
 
 
1212
        # create rename entries and tuples
 
1213
        from_tail = splitpath(from_rel)[-1]
 
1214
        from_id = inv.path2id(from_rel)
 
1215
        if from_id is None:
 
1216
            raise errors.BzrRenameFailedError(from_rel,to_rel,
 
1217
                errors.NotVersionedError(path=str(from_rel)))
 
1218
        from_entry = inv[from_id]
 
1219
        from_parent_id = from_entry.parent_id
1086
1220
        to_dir, to_tail = os.path.split(to_rel)
1087
1221
        to_dir_id = inv.path2id(to_dir)
1088
 
        if to_dir_id is None and to_dir != '':
1089
 
            raise BzrError("can't determine destination directory id for %r" % to_dir)
1090
 
 
1091
 
        mutter("rename_one:")
1092
 
        mutter("  file_id    {%s}" % file_id)
1093
 
        mutter("  from_rel   %r" % from_rel)
1094
 
        mutter("  to_rel     %r" % to_rel)
1095
 
        mutter("  to_dir     %r" % to_dir)
1096
 
        mutter("  to_dir_id  {%s}" % to_dir_id)
1097
 
 
1098
 
        inv.rename(file_id, to_dir_id, to_tail)
1099
 
 
1100
 
        from_abs = self.abspath(from_rel)
1101
 
        to_abs = self.abspath(to_rel)
1102
 
        try:
1103
 
            osutils.rename(from_abs, to_abs)
1104
 
        except OSError, e:
1105
 
            inv.rename(file_id, from_parent, from_name)
1106
 
            raise BzrError("failed to rename %r to %r: %s"
1107
 
                    % (from_abs, to_abs, e[1]))
 
1222
        rename_entry = WorkingTree._RenameEntry(from_rel=from_rel,
 
1223
                                     from_id=from_id,
 
1224
                                     from_tail=from_tail,
 
1225
                                     from_parent_id=from_parent_id,
 
1226
                                     to_rel=to_rel, to_tail=to_tail,
 
1227
                                     to_parent_id=to_dir_id)
 
1228
        rename_entries.append(rename_entry)
 
1229
 
 
1230
        # determine which move mode to use. checks also for movability
 
1231
        rename_entries = self._determine_mv_mode(rename_entries, after)
 
1232
 
 
1233
        # check if the target changed directory and if the target directory is
 
1234
        # versioned
 
1235
        if to_dir_id is None:
 
1236
            raise errors.BzrMoveFailedError(from_rel,to_rel,
 
1237
                errors.NotVersionedError(path=str(to_dir)))
 
1238
 
 
1239
        # all checks done. now we can continue with our actual work
 
1240
        mutter('rename_one:\n'
 
1241
               '  from_id   {%s}\n'
 
1242
               '  from_rel: %r\n'
 
1243
               '  to_rel:   %r\n'
 
1244
               '  to_dir    %r\n'
 
1245
               '  to_dir_id {%s}\n',
 
1246
               from_id, from_rel, to_rel, to_dir, to_dir_id)
 
1247
 
 
1248
        self._move(rename_entries)
1108
1249
        self._write_inventory(inv)
1109
1250
 
 
1251
    class _RenameEntry(object):
 
1252
        def __init__(self, from_rel, from_id, from_tail, from_parent_id,
 
1253
                     to_rel, to_tail, to_parent_id, only_change_inv=False):
 
1254
            self.from_rel = from_rel
 
1255
            self.from_id = from_id
 
1256
            self.from_tail = from_tail
 
1257
            self.from_parent_id = from_parent_id
 
1258
            self.to_rel = to_rel
 
1259
            self.to_tail = to_tail
 
1260
            self.to_parent_id = to_parent_id
 
1261
            self.only_change_inv = only_change_inv
 
1262
 
1110
1263
    @needs_read_lock
1111
1264
    def unknowns(self):
1112
1265
        """Return all unknown files.
1490
1643
            if not fid:
1491
1644
                # TODO: Perhaps make this just a warning, and continue?
1492
1645
                # This tends to happen when 
1493
 
                raise NotVersionedError(path=f)
 
1646
                raise errors.NotVersionedError(path=f)
1494
1647
            if verbose:
1495
1648
                # having remove it, it must be either ignored or unknown
1496
1649
                if self.is_ignored(f):
1539
1692
            elif kind == 'symlink':
1540
1693
                inv.add(InventoryLink(file_id, name, parent))
1541
1694
            else:
1542
 
                raise BzrError("unknown kind %r" % kind)
 
1695
                raise errors.BzrError("unknown kind %r" % kind)
1543
1696
        self._write_inventory(inv)
1544
1697
 
1545
1698
    @needs_tree_write_lock
1720
1873
        self.flush()
1721
1874
 
1722
1875
    def set_conflicts(self, arg):
1723
 
        raise UnsupportedOperation(self.set_conflicts, self)
 
1876
        raise errors.UnsupportedOperation(self.set_conflicts, self)
1724
1877
 
1725
1878
    def add_conflicts(self, arg):
1726
 
        raise UnsupportedOperation(self.add_conflicts, self)
 
1879
        raise errors.UnsupportedOperation(self.add_conflicts, self)
1727
1880
 
1728
1881
    @needs_read_lock
1729
1882
    def conflicts(self):
1803
1956
        """See Mutable.last_revision."""
1804
1957
        try:
1805
1958
            return self._control_files.get_utf8('last-revision').read()
1806
 
        except NoSuchFile:
 
1959
        except errors.NoSuchFile:
1807
1960
            return None
1808
1961
 
1809
1962
    def _change_last_revision(self, revision_id):
1834
1987
    def conflicts(self):
1835
1988
        try:
1836
1989
            confile = self._control_files.get('conflicts')
1837
 
        except NoSuchFile:
 
1990
        except errors.NoSuchFile:
1838
1991
            return _mod_conflicts.ConflictList()
1839
1992
        try:
1840
1993
            if confile.next() != CONFLICT_HEADER_1 + '\n':
1841
 
                raise ConflictFormatError()
 
1994
                raise errors.ConflictFormatError()
1842
1995
        except StopIteration:
1843
 
            raise ConflictFormatError()
 
1996
            raise errors.ConflictFormatError()
1844
1997
        return _mod_conflicts.ConflictList.from_stanzas(RioReader(confile))
1845
1998
 
1846
1999
    def unlock(self):
1908
2061
            transport = a_bzrdir.get_workingtree_transport(None)
1909
2062
            format_string = transport.get("format").read()
1910
2063
            return klass._formats[format_string]
1911
 
        except NoSuchFile:
 
2064
        except errors.NoSuchFile:
1912
2065
            raise errors.NoWorkingTree(base=transport.base)
1913
2066
        except KeyError:
1914
2067
            raise errors.UnknownFormatError(format=format_string)