diff --git a/dvc/stage.py b/dvc/stage.py index 30098c977..8aeff60a5 100644 --- a/dvc/stage.py +++ b/dvc/stage.py @@ -284,10 +284,17 @@ class Output(Dependency): md5 = file_md5(path)[0] cache = self.project.cache.get(md5) cache_info = os.path.join(self.cache, relpath) + cache_dir = os.path.dirname(cache_info) - self.hardlink(path, cache) + if os.path.exists(cache): + self._remove(path, None) + self.hardlink(cache, path) + else: + self.hardlink(path, cache) + + if not os.path.exists(cache_dir): + os.makedirs(cache_dir) - os.makedirs(os.path.dirname(cache_info)) with open(cache_info, 'w') as fd: yaml.safe_dump({self.PARAM_MD5: md5}, fd, default_flow_style=False) diff --git a/test-requirements.txt b/test-requirements.txt index a719f4228..5e847837e 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -2,3 +2,4 @@ coverage==4.3.1 codeclimate-test-reporter==0.2.3 xmltodict==0.11.0 awscli==1.14.18 +pywin32; sys_platform == 'nt' diff --git a/tests/test_add.py b/tests/test_add.py index 0f823bbfd..9b5b1e0a8 100644 --- a/tests/test_add.py +++ b/tests/test_add.py @@ -1,4 +1,5 @@ import os +import stat import shutil import filecmp from checksumdir import dirhash @@ -59,6 +60,25 @@ class TestAddTrackedFile(TestDvc): self.dvc.add(fname) +class TestAddDirWithExistingCache(TestDvc): + def test(self): + dname = 'a' + fname = os.path.join(dname, 'b') + os.mkdir(dname) + shutil.copyfile(self.FOO, fname) + + self.dvc.add(self.FOO) + self.dvc.add(dname) + + +class TestAddModifiedDir(TestDvc): + def test(self): + self.dvc.add(self.DATA_DIR) + os.chmod(self.DATA, stat.S_IWRITE) + os.unlink(self.DATA) + self.dvc.add(self.DATA_DIR) + + class TestCmdAdd(TestDvc): def test(self): ret = main(['add',