mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-02 07:18:25 +01:00
sftp: make move an atomic operation
This commit is contained in:
@@ -185,17 +185,18 @@ class SSHConnection:
|
||||
self.sftp.get(src, dest, callback=pbar.update_to)
|
||||
|
||||
def move(self, src, dst):
|
||||
"""Use `SFTP RENAME` operation when possible, otherwise,
|
||||
fallback to copy and remove, since the former one doesn't
|
||||
work across drives.
|
||||
"""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.
|
||||
"""
|
||||
self.makedirs(posixpath.dirname(dst))
|
||||
|
||||
try:
|
||||
self.sftp.rename(src, dst)
|
||||
except OSError:
|
||||
self.copy(src, dst)
|
||||
self.remove(src)
|
||||
tmp = tmp_fname(dst)
|
||||
self.copy(src, tmp)
|
||||
self.sftp.rename(tmp, dst)
|
||||
self.remove(src)
|
||||
|
||||
def upload(self, src, dest, no_progress_bar=False, progress_title=None):
|
||||
self.makedirs(posixpath.dirname(dest))
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user