diff --git a/dvc/repo/data.py b/dvc/repo/data.py index 95cca2cf4..398a0aab9 100644 --- a/dvc/repo/data.py +++ b/dvc/repo/data.py @@ -215,6 +215,17 @@ class Status(TypedDict): git: GitInfo +def _transform_git_paths_to_dvc(repo: "Repo", files: List[str]): + """Transform files rel. to Git root to DVC root, and drop outside files.""" + rel = repo.fs.path.relpath(repo.root_dir, repo.scm.root_dir).rstrip("/") + if rel in (os.curdir, ""): + return files + + prefix = rel + os.sep + length = len(prefix) + return [file[length:] for file in files if file.startswith(prefix)] + + def status(repo: "Repo", untracked_files: str = "no", **kwargs: Any) -> Status: from scmrepo.exceptions import SCMError @@ -235,12 +246,14 @@ def status(repo: "Repo", untracked_files: str = "no", **kwargs: Any) -> Status: unchanged &= set(committed_diff.pop("unchanged", [])) git_info = _git_info(repo.scm, untracked_files=untracked_files) + untracked = git_info.get("untracked", []) + untracked = _transform_git_paths_to_dvc(repo, untracked) # order matters here return Status( not_in_cache=not_in_cache, committed=committed_diff, uncommitted=uncommitted_diff, - untracked=git_info.get("untracked", []), + untracked=untracked, unchanged=list(unchanged), git=git_info, ) diff --git a/tests/func/test_data_status.py b/tests/func/test_data_status.py index 989480798..e6bcb0d14 100644 --- a/tests/func/test_data_status.py +++ b/tests/func/test_data_status.py @@ -1,6 +1,7 @@ from os.path import join from dvc.repo import Repo +from dvc.testing.tmp_dir import make_subrepo from dvc.utils.fs import remove EMPTY_STATUS = { @@ -146,3 +147,21 @@ def test_skip_uncached_pipeline_outputs(tmp_dir, dvc, run_copy_metrics): def test_output_with_newly_added_stage(tmp_dir, dvc): dvc.stage.add(deps=["bar"], outs=["foo"], name="copy", cmd="cp foo bar") assert dvc.data_status() == {**EMPTY_STATUS, "not_in_cache": ["foo"]} + + +def test_subdir(M, tmp_dir, scm): + subrepo = tmp_dir / "sub" + make_subrepo(subrepo, scm) + + with subrepo.chdir(): + subrepo.dvc_gen({"dir": {"foo": "foo"}}, commit="add dir") + subrepo.dvc_gen("bar", "bar", commit="add foo") + subrepo.gen("untracked", "untracked") + + dvc = subrepo.dvc + assert dvc.data_status(granular=True, untracked_files="all") == { + **EMPTY_STATUS, + "git": M.instance_of(dict), + "unchanged": M.unordered("bar", join("dir", "foo")), + "untracked": ["untracked"], + }