Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions dvc/repo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,15 +387,24 @@ def get_data_index_entry(
path: str,
workspace: str = "repo",
) -> tuple["DataIndex", "DataIndexEntry"]:
abspath = path
if not os.path.isabs(abspath):
# `path` is interpreted as relative to the root of the repo, not
# the current working directory (which may be a subdirectory of
# the repo). See #11029.
abspath = self.fs.join(self.root_dir, abspath)
if self.subrepos:
fs_path = self.dvcfs.from_os_path(path)
# `from_os_path` returns a path relative to the repo root. Anchor
# it at the filesystem root so it is not re-resolved against the
# filesystem's current working directory.
fs_path = self.dvcfs.from_os_path(abspath)
fs = self.dvcfs.fs
key = fs._get_key_from_relative(fs_path)
key = fs._get_key_from_relative(fs.root_marker + 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(abspath, self.root_dir)

try:
return index, index[key]
Expand Down
16 changes: 16 additions & 0 deletions tests/func/api/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,22 @@ def test_get_url_granular(tmp_dir, dvc, cloud):
assert api.get_url(os.path.join("dir", "nested", "file")) == expected_url


def test_get_url_from_subdir(tmp_dir, dvc, local_cloud):
tmp_dir.add_remote(config=local_cloud.config)
tmp_dir.dvc_gen({"foo": "foo", "subdir": {"bar": "bar"}})

expected_url = (
local_cloud / "files" / "md5" / "ac" / "bd18db4cc2f85cedef654fccc4a4d8"
).url

# A relative path is relative to the root of the repo, even when the
# current working directory is a subdirectory of the repo (#11029).
subdir = tmp_dir / "subdir"
with subdir.chdir():
assert api.get_url("foo") == expected_url
assert api.get_url("foo", repo=os.fspath(tmp_dir)) == expected_url


def test_get_url_subrepos(tmp_dir, scm, local_cloud):
subrepo = tmp_dir / "subrepo"
make_subrepo(subrepo, scm, config=local_cloud.config)
Expand Down
Loading