mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-02 07:18:25 +01:00
checkout: Remove selectively on directory files when changed (#1320)
Fix: #1220
This commit is contained in:
+2
-4
@@ -465,12 +465,10 @@ class Project(object):
|
||||
|
||||
def checkout(self, target=None, with_deps=False):
|
||||
all_stages = self.active_stages()
|
||||
stages = all_stages
|
||||
|
||||
if target:
|
||||
stages = self._collect(target,
|
||||
with_deps=with_deps)
|
||||
else:
|
||||
stages = all_stages
|
||||
stages = self._collect(target, with_deps=with_deps)
|
||||
|
||||
with self.state:
|
||||
self._cleanup_unused_links(all_stages)
|
||||
|
||||
+20
-7
@@ -270,7 +270,7 @@ class RemoteLOCAL(RemoteBase):
|
||||
|
||||
def checkout(self, path_info, checksum_info):
|
||||
path = path_info['path']
|
||||
md5 = checksum_info.get(self.PARAM_MD5, None)
|
||||
md5 = checksum_info.get(self.PARAM_MD5)
|
||||
cache = self.get(md5)
|
||||
|
||||
if not cache:
|
||||
@@ -289,15 +289,16 @@ class RemoteLOCAL(RemoteBase):
|
||||
remove(path)
|
||||
return
|
||||
|
||||
if os.path.exists(path):
|
||||
msg = u'Data \'{}\' exists. Removing before checkout.'
|
||||
Logger.warn(msg.format(os.path.relpath(path)))
|
||||
remove(path)
|
||||
|
||||
msg = u'Checking out \'{}\' with cache \'{}\'.'
|
||||
Logger.info(msg.format(os.path.relpath(path), md5))
|
||||
|
||||
if not self.is_dir_cache(cache):
|
||||
|
||||
if os.path.exists(path):
|
||||
msg = u'File \'{}\' exists. Removing before checkout.'
|
||||
Logger.warn(msg.format(os.path.relpath(path)))
|
||||
remove(path)
|
||||
|
||||
self.link(cache, path)
|
||||
self.state.update_link(path)
|
||||
return
|
||||
@@ -319,7 +320,19 @@ class RemoteLOCAL(RemoteBase):
|
||||
m = entry[self.PARAM_MD5]
|
||||
p = os.path.join(path, relpath)
|
||||
c = self.get(m)
|
||||
self.link(c, p)
|
||||
|
||||
entry_info = {
|
||||
'scheme': path_info['scheme'],
|
||||
self.PARAM_PATH: p,
|
||||
}
|
||||
|
||||
entry_checksum_info = {
|
||||
self.PARAM_MD5: m,
|
||||
}
|
||||
|
||||
if self.changed(entry_info, entry_checksum_info):
|
||||
remove(p)
|
||||
self.link(c, p)
|
||||
|
||||
if bar:
|
||||
progress.update_target(dir_relpath, processed, dir_size)
|
||||
|
||||
@@ -4,9 +4,11 @@ import time
|
||||
import stat
|
||||
import shutil
|
||||
import filecmp
|
||||
import collections
|
||||
|
||||
from dvc.main import main
|
||||
from dvc.project import Project
|
||||
from dvc.system import System
|
||||
from tests.basic_env import TestDvc
|
||||
from tests.test_repro import TestRepro
|
||||
from dvc.stage import Stage
|
||||
@@ -116,6 +118,20 @@ class CheckoutBase(TestDvc):
|
||||
def read_ignored(self):
|
||||
return list(map(lambda s: s.strip('\n'), open(self.GIT_IGNORE).readlines()))
|
||||
|
||||
def outs_info(self, stage):
|
||||
FileInfo = collections.namedtuple('FileInfo', 'path inode')
|
||||
|
||||
paths = [
|
||||
os.path.join(root, file)
|
||||
for output in stage.outs
|
||||
for root, _, files in os.walk(output.path)
|
||||
for file in files
|
||||
]
|
||||
|
||||
return [
|
||||
FileInfo(path=path, inode=System.inode(path))
|
||||
for path in paths
|
||||
]
|
||||
|
||||
class TestRemoveFilesWhenCheckout(CheckoutBase):
|
||||
def test(self):
|
||||
@@ -143,6 +159,29 @@ class TestRemoveFilesWhenCheckout(CheckoutBase):
|
||||
self.assertFalse(os.path.exists(fname))
|
||||
|
||||
|
||||
class TestCheckoutSelectiveRemove(CheckoutBase):
|
||||
def test(self):
|
||||
# Use copy to test for changes in the inodes
|
||||
ret = main(['config', 'cache.type', 'copy'])
|
||||
self.assertEqual(ret, 0)
|
||||
|
||||
stages = self.dvc.add(self.DATA_DIR)
|
||||
self.assertEqual(len(stages), 1)
|
||||
stage = stages[0]
|
||||
staged_files = self.outs_info(stage)
|
||||
|
||||
os.remove(staged_files[0].path)
|
||||
ret = main(['checkout', stage.relpath])
|
||||
self.assertEqual(ret, 0)
|
||||
|
||||
checkedout_files = self.outs_info(stage)
|
||||
|
||||
self.assertEqual(len(staged_files), len(checkedout_files))
|
||||
self.assertEqual(staged_files[0].path, checkedout_files[0].path)
|
||||
self.assertNotEqual(staged_files[0].inode, checkedout_files[0].inode)
|
||||
self.assertEqual(staged_files[1].inode, checkedout_files[1].inode)
|
||||
|
||||
|
||||
class TestGitIgnoreBasic(CheckoutBase):
|
||||
def test(self):
|
||||
fname1 = 'file_1'
|
||||
|
||||
Reference in New Issue
Block a user