From 16164e65ad1f036aca2dc3c408e177af98f8c635 Mon Sep 17 00:00:00 2001 From: "Mr. Outis" Date: Fri, 1 Nov 2019 16:56:55 -0600 Subject: [PATCH] sftp: move -> use atomic copying --- dvc/remote/ssh/connection.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/dvc/remote/ssh/connection.py b/dvc/remote/ssh/connection.py index fa2e8a5ee9..b2da0b67ac 100644 --- a/dvc/remote/ssh/connection.py +++ b/dvc/remote/ssh/connection.py @@ -185,24 +185,28 @@ def download(self, src, dest, no_progress_bar=False, progress_title=None): self.sftp.get(src, dest, callback=pbar.update_to) def move(self, src, dst): - """Atomically move src to dst. - - Moving is performed in two stages to make the whole operation atomic in - case src and dst are on different filesystems and actual physical - copying of data is happening. + """Rename src to dst, if it is not possible (in case src and dst are + on different filesystems) and actual physical copying of data is + happening. """ self.makedirs(posixpath.dirname(dst)) - tmp = tmp_fname(dst) - try: - self.sftp.rename(src, tmp) + self.sftp.rename(src, dst) except OSError: - self.copy(src, tmp) + self._atomic_copy(src, dst) - self.sftp.rename(tmp, dst) self.remove(src) + def _atomic_copy(self, src, dst): + tmp = tmp_fname(dst) + + try: + self.copy(src, tmp) + self.sftp.rename(tmp, dst) + finally: + self.remove(tmp) + def upload(self, src, dest, no_progress_bar=False, progress_title=None): self.makedirs(posixpath.dirname(dest)) tmp_file = tmp_fname(dest)