diff --git a/dvc/command/remove.py b/dvc/command/remove.py index b8e98200c..814adcfae 100644 --- a/dvc/command/remove.py +++ b/dvc/command/remove.py @@ -74,9 +74,6 @@ def add_parser(subparsers, parent_parser): help="Force purge.", ) remove_parser.add_argument( - "targets", - nargs="+", - help="DVC-files to remove. Optional. " - "(Finds all DVC-files in the workspace by default.)", + "targets", nargs="+", help="DVC-files to remove." ) remove_parser.set_defaults(func=CmdRemove) diff --git a/dvc/exceptions.py b/dvc/exceptions.py index bddf83ec9..8648f69e7 100644 --- a/dvc/exceptions.py +++ b/dvc/exceptions.py @@ -279,3 +279,10 @@ class DvcIgnoreInCollectedDirError(DvcException): ".dvcignore file should not be in collected dir path: " "'{}'".format(ignore_dirname) ) + + +class UrlNotDvcRepoError(DvcException): + def __init__(self, url): + super(UrlNotDvcRepoError, self).__init__( + "URL '{}' is not a dvc repository.".format(url) + ) diff --git a/dvc/repo/get.py b/dvc/repo/get.py index e8ea9ba0e..b0e23618a 100644 --- a/dvc/repo/get.py +++ b/dvc/repo/get.py @@ -1,13 +1,17 @@ +import logging import os import shortuuid from dvc.config import Config +from dvc.exceptions import NotDvcRepoError, UrlNotDvcRepoError from dvc.path_info import PathInfo from dvc.external_repo import external_repo from dvc.state import StateNoop from dvc.utils import remove from dvc.utils.compat import urlparse +logger = logging.getLogger(__name__) + @staticmethod def get(url, path, out=None, rev=None): @@ -48,5 +52,8 @@ def get(url, path, out=None, rev=None): o.path_info = PathInfo(os.path.abspath(out)) with o.repo.state: o.checkout() + + except NotDvcRepoError: + raise UrlNotDvcRepoError(url) finally: remove(tmp_dir) diff --git a/dvc/stage.py b/dvc/stage.py index 142e94094..cc91c81e0 100644 --- a/dvc/stage.py +++ b/dvc/stage.py @@ -505,8 +505,6 @@ class Stage(object): stage.remove_outs(ignore_remove=False) logger.warning("Build cache is ignored when using --remove-outs.") ignore_build_cache = True - else: - stage.unprotect_outs() if os.path.exists(path) and any(out.persist for out in stage.outs): logger.warning("Build cache is ignored when persisting outputs.") diff --git a/dvc/version.py b/dvc/version.py index 5433dbd22..218652782 100644 --- a/dvc/version.py +++ b/dvc/version.py @@ -7,7 +7,7 @@ import os import subprocess -_BASE_VERSION = "0.57.0" +_BASE_VERSION = "0.58.1" def _generate_version(base_version): diff --git a/tests/conftest.py b/tests/conftest.py index 051d2b7a9..62355b02c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -9,8 +9,7 @@ from dvc.remote.config import RemoteConfig from dvc.utils.compat import cast_bytes_py2 from dvc.remote.ssh.connection import SSHConnection from dvc.repo import Repo as DvcRepo -from .basic_env import TestDirFixture, TestDvcGitFixture - +from .basic_env import TestDirFixture, TestDvcGitFixture, TestGitFixture # Prevent updater and analytics from running their processes os.environ[cast_bytes_py2("DVC_TEST")] = cast_bytes_py2("true") @@ -187,3 +186,11 @@ def chdir_tmp(tmp_path): yield finally: os.chdir(cwd) + + +@pytest.fixture +def git_erepo(): + repo = TestGitFixture() + repo.setUp() + yield repo + repo.tearDown() diff --git a/tests/func/test_add.py b/tests/func/test_add.py index a9c52185c..6e7516c49 100644 --- a/tests/func/test_add.py +++ b/tests/func/test_add.py @@ -12,6 +12,7 @@ import posixpath import logging import colorama +from dvc.remote import RemoteLOCAL from dvc.system import System from mock import patch @@ -535,3 +536,20 @@ def test_windows_should_add_when_cache_on_different_drive( ret = main(["add", repo_dir.DATA]) assert ret == 0 + + +def test_readding_dir_should_not_unprotect_all(dvc_repo, repo_dir): + dvc_repo.cache.local.cache_types = ["symlink"] + dvc_repo.cache.local.protected = True + + dvc_repo.add(repo_dir.DATA_DIR) + new_file = os.path.join(repo_dir.DATA_DIR, "new_file") + + repo_dir.create(new_file, "new_content") + + unprotect_spy = spy(RemoteLOCAL.unprotect) + with patch.object(RemoteLOCAL, "unprotect", unprotect_spy): + dvc_repo.add(repo_dir.DATA_DIR) + + assert not unprotect_spy.mock.called + assert System.is_symlink(new_file) diff --git a/tests/func/test_get.py b/tests/func/test_get.py index b545f1d4a..62d86816d 100644 --- a/tests/func/test_get.py +++ b/tests/func/test_get.py @@ -1,6 +1,9 @@ import os import filecmp +import pytest + +from dvc.exceptions import UrlNotDvcRepoError from dvc.repo import Repo from tests.utils import trees_equal @@ -38,3 +41,8 @@ def test_get_repo_rev(repo_dir, erepo): assert os.path.isfile(dst) with open(dst, "r+") as fobj: assert fobj.read() == "branch" + + +def test_get_from_non_dvc_repo(git_erepo): + with pytest.raises(UrlNotDvcRepoError): + Repo.get(git_erepo.root_dir, "some_file.zip")