Skip to content

Commit

Permalink
Merge pull request #2709 from mroutis/fix-2704
Browse files Browse the repository at this point in the history
sftp: make move across drives possible
  • Loading branch information
efiop authored Nov 2, 2019
2 parents 91a7af0 + 16164e6 commit 2e6485f
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
21 changes: 20 additions & 1 deletion dvc/remote/ssh/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,27 @@ 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):
"""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))
self.sftp.rename(src, dst)

try:
self.sftp.rename(src, dst)
except OSError:
self._atomic_copy(src, 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))
Expand Down
6 changes: 6 additions & 0 deletions tests/unit/remote/ssh/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,9 @@ def test_hardlink(repo_dir, ssh):
def test_copy(repo_dir, ssh):
ssh.copy("foo", "link")
assert filecmp.cmp("foo", "link")


def test_move(repo_dir, ssh):
ssh.move("foo", "copy")
assert os.path.exists("copy")
assert not os.path.exists("foo")

0 comments on commit 2e6485f

Please sign in to comment.