diff --git a/dvc/repo/__init__.py b/dvc/repo/__init__.py index a7c3d4d7ca..612f9aa8d4 100644 --- a/dvc/repo/__init__.py +++ b/dvc/repo/__init__.py @@ -387,15 +387,17 @@ def get_data_index_entry( path: str, workspace: str = "repo", ) -> tuple["DataIndex", "DataIndexEntry"]: + fs_path = path if self.fs.isabs(path) else self.fs.join(self.root_dir, path) if self.subrepos: - fs_path = self.dvcfs.from_os_path(path) + fs_path = self.dvcfs.from_os_path(fs_path) + fs_path = self.dvcfs.join(self.dvcfs.root_marker, fs_path) fs = self.dvcfs.fs key = fs._get_key_from_relative(fs_path) subrepo, _, key = fs._get_subrepo_info(key) index = subrepo.index.data[workspace] else: index = self.index.data[workspace] - key = self.fs.relparts(path, self.root_dir) + key = self.fs.relparts(fs_path, self.root_dir) try: return index, index[key] diff --git a/tests/func/api/test_data.py b/tests/func/api/test_data.py index 48d4e98eed..596853866c 100644 --- a/tests/func/api/test_data.py +++ b/tests/func/api/test_data.py @@ -94,6 +94,20 @@ def test_get_url_ignore_scm(tmp_dir, dvc, cloud, scm): api.get_url("foo", repo=repo_url, config={"core": {"no_scm": True}}) +def test_get_url_with_explicit_repo_from_subdir(tmp_dir, dvc, scm, cloud): + tmp_dir.add_remote(config=cloud.config) + tmp_dir.dvc_gen("foo", "foo", commit="add foo") + (tmp_dir / "subdir").mkdir() + + expected_url = ( + cloud / "files" / "md5" / "ac" / "bd18db4cc2f85cedef654fccc4a4d8" + ).url + with (tmp_dir / "subdir").chdir(): + assert api.get_url("foo", repo=os.fspath(tmp_dir)) == expected_url + _, entry = dvc.get_data_index_entry("foo") + assert entry.hash_info.value == "acbd18db4cc2f85cedef654fccc4a4d8" + + def test_open_external(tmp_dir, erepo_dir, cloud): erepo_dir.add_remote(config=cloud.config) @@ -262,6 +276,13 @@ def test_get_url_subrepos(tmp_dir, scm, local_cloud): ) assert api.get_url(os.path.join("subrepo", "dir", "foo")) == expected_url assert api.get_url(os.path.join("subrepo", "dir", "foo"), repo=".") == expected_url + subdir = tmp_dir / "subdir" + subdir.mkdir() + with subdir.chdir(): + assert ( + api.get_url(os.path.join("subrepo", "dir", "foo"), repo=os.fspath(tmp_dir)) + == expected_url + ) expected_url = os.fspath( local_cloud / "files" / "md5" / "37" / "b51d194a7513e45b56f6524f2d51f2"