201
201
"""Rename a file or directory; fail if the destination exists"""
202
202
abs_from = self._abspath(rel_from)
203
203
abs_to = self._abspath(rel_to)
205
206
if x == abs_from:
207
208
elif x.startswith(abs_from + '/'):
208
209
x = abs_to + x[len(abs_from):]
210
212
def do_renames(container):
211
214
for path in container:
212
215
new_path = replace(path)
213
216
if new_path != path:
214
217
if new_path in container:
215
218
raise FileExists(new_path)
216
container[new_path] = container[path]
218
do_renames(self._files)
219
do_renames(self._dirs)
219
renames.append((path, new_path))
220
for path, new_path in renames:
221
container[new_path] = container[path]
224
# If we modify the existing dicts, we're not atomic anymore and may
225
# fail differently depending on dict order. So work on copy, fail on
226
# error on only replace dicts if all goes well.
227
renamed_files = self._files.copy()
228
renamed_dirs = self._dirs.copy()
229
do_renames(renamed_files)
230
do_renames(renamed_dirs)
231
# We may have been cloned so modify in place
233
self._files.update(renamed_files)
235
self._dirs.update(renamed_dirs)
221
237
def rmdir(self, relpath):
222
238
"""See Transport.rmdir."""