Skip to content

Commit 2e6485f

Browse files
authored
Merge pull request #2709 from mroutis/fix-2704
sftp: make move across drives possible
2 parents 91a7af0 + 16164e6 commit 2e6485f

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

dvc/remote/ssh/connection.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,27 @@ def download(self, src, dest, no_progress_bar=False, progress_title=None):
185185
self.sftp.get(src, dest, callback=pbar.update_to)
186186

187187
def move(self, src, dst):
188+
"""Rename src to dst, if it is not possible (in case src and dst are
189+
on different filesystems) and actual physical copying of data is
190+
happening.
191+
"""
188192
self.makedirs(posixpath.dirname(dst))
189-
self.sftp.rename(src, dst)
193+
194+
try:
195+
self.sftp.rename(src, dst)
196+
except OSError:
197+
self._atomic_copy(src, dst)
198+
199+
self.remove(src)
200+
201+
def _atomic_copy(self, src, dst):
202+
tmp = tmp_fname(dst)
203+
204+
try:
205+
self.copy(src, tmp)
206+
self.sftp.rename(tmp, dst)
207+
finally:
208+
self.remove(tmp)
190209

191210
def upload(self, src, dest, no_progress_bar=False, progress_title=None):
192211
self.makedirs(posixpath.dirname(dest))

tests/unit/remote/ssh/test_connection.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,9 @@ def test_hardlink(repo_dir, ssh):
111111
def test_copy(repo_dir, ssh):
112112
ssh.copy("foo", "link")
113113
assert filecmp.cmp("foo", "link")
114+
115+
116+
def test_move(repo_dir, ssh):
117+
ssh.move("foo", "copy")
118+
assert os.path.exists("copy")
119+
assert not os.path.exists("foo")

0 commit comments

Comments
 (0)