diff --git a/dvc/external_repo.py b/dvc/external_repo.py index 7dd6afc523..8e46569b33 100644 --- a/dvc/external_repo.py +++ b/dvc/external_repo.py @@ -84,7 +84,7 @@ def pull_to(self, path, to_info): try: if out and out.use_cache: - self._pull_cached(out, path, to_info) + self._pull_cached(out, path_info, to_info) return # Check if it is handled by Git (it can't have an absolute path) @@ -95,11 +95,10 @@ def pull_to(self, path, to_info): except FileNotFoundError: raise PathMissingError(path, self.url) - def _pull_cached(self, out, src, dest): + def _pull_cached(self, out, path_info, dest): with self.state: tmp = PathInfo(tmp_fname(dest)) - target = (out.path_info.parent / src).relative_to(out.path_info) - src = tmp / target + src = tmp / path_info.relative_to(out.path_info) out.path_info = tmp diff --git a/tests/func/test_external_repo.py b/tests/func/test_external_repo.py index 46103fbb8a..d1a23de462 100644 --- a/tests/func/test_external_repo.py +++ b/tests/func/test_external_repo.py @@ -1,3 +1,5 @@ +import os + from mock import patch from dvc.compat import fspath @@ -71,3 +73,18 @@ def test_known_sha(erepo_dir): # No clone, no pull, copies a repo, checks out the known sha with external_repo(url, prev_rev) as repo: pass + + +def test_pull_subdir_file(tmp_dir, erepo_dir): + with erepo_dir.chdir(): + subdir = erepo_dir / "subdir" + subdir.mkdir() + (subdir / "file").write_text("contents") + erepo_dir.dvc_add(subdir / "file", commit="create file") + + dest = tmp_dir / "file" + with external_repo(fspath(erepo_dir)) as repo: + repo.pull_to(os.path.join("subdir", "file"), dest) + + assert dest.is_file() + assert dest.read_text() == "contents"