unprotect: only process symlinks and hardlinks

Fixes #1373

Signed-off-by: Ruslan Kuprieiev <[email protected]>
This commit is contained in:
Ruslan Kuprieiev
2018-12-04 10:57:53 +02:00
parent a7c177d757
commit 2d9ec1005b
2 changed files with 29 additions and 5 deletions
+10 -5
View File
@@ -325,16 +325,21 @@ class Project(object):
def _unprotect_file(self, path):
import stat
import uuid
from dvc.system import System
from dvc.utils import copyfile, move, remove
self.logger.debug("Unprotecting '{}'".format(path))
if System.is_symlink(path) or System.is_hardlink(path):
self.logger.debug("Unprotecting '{}'".format(path))
tmp = os.path.join(os.path.dirname(path), '.' + str(uuid.uuid4()))
move(path, tmp)
tmp = os.path.join(os.path.dirname(path), '.' + str(uuid.uuid4()))
move(path, tmp)
copyfile(tmp, path)
copyfile(tmp, path)
remove(tmp)
remove(tmp)
else:
self.logger.debug("Skipping copying for '{}', since it is not "
"a symlink or a hardlink.".format(path))
os.chmod(path, os.stat(path).st_mode | stat.S_IWRITE)
+19
View File
@@ -240,3 +240,22 @@ class System(object):
return System._wait_for_input_posix(timeout)
else:
return System._wait_for_input_windows(timeout)
@staticmethod
def is_symlink(path):
if System.is_unix():
return os.path.islink(path)
# https://docs.microsoft.com/en-us/windows/desktop/fileio/
# file-attribute-constants
FILE_ATTRIBUTE_REPARSE_POINT = 0x400
info = System.getdirinfo(path)
return info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT
@staticmethod
def is_hardlink(path):
if System.is_unix():
return os.stat(path).st_nlink > 1
info = System.getdirinfo(path)
return info.nNumberOfLinks > 1