diff --git a/dvc/output.py b/dvc/output.py index 8b0d0e3db..2b1bd17f5 100644 --- a/dvc/output.py +++ b/dvc/output.py @@ -95,7 +95,7 @@ class Dependency(object): return os.path.getmtime(self.path) def inode(self): - return os.stat(self.path).st_ino + return System.inode(self.path) def save(self): if not os.path.exists(self.path): diff --git a/dvc/system.py b/dvc/system.py index 174414626..7ad86f541 100644 --- a/dvc/system.py +++ b/dvc/system.py @@ -6,6 +6,7 @@ from builtins import str if os.name == 'nt': import ntfsutils.hardlink as winlink + from ntfsutils.fs import * class System(object): @@ -23,6 +24,29 @@ class System(object): return winlink.create(source, link_name) + @staticmethod + def _getfileinfo(path): + # FIXME: current implementation from ntfsutils doesn't support dirs, + # and until https://github.com/sid0/ntfs/pull/10 is not merged and + # pip package not updated, we have to use our own version. + hfile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, None, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, None) + if hfile is None: + raise WinError() + info = BY_HANDLE_FILE_INFORMATION() + rv = GetFileInformationByHandle(hfile, info) + CloseHandle(hfile) + if rv == 0: + raise WinError() + return info + + @staticmethod + def inode(path): + if System.is_unix(): + return os.stat(path).st_ino + + info = System._getfileinfo(path) + return hash((info.dwVolumeSerialNumber, info.nFileIndexHigh, info.nFileIndexLow)) + @staticmethod def samefile(path1, path2): if not os.path.exists(path1) or not os.path.exists(path2):