diff --git a/dvc/repo/data.py b/dvc/repo/data.py index 2dfa10d10..6a4d25259 100644 --- a/dvc/repo/data.py +++ b/dvc/repo/data.py @@ -1,4 +1,5 @@ import os +import posixpath from collections import defaultdict from typing import ( TYPE_CHECKING, @@ -11,6 +12,7 @@ from typing import ( cast, ) +from dvc.fs.git import GitFileSystem from dvc.ui import ui if TYPE_CHECKING: @@ -23,6 +25,10 @@ if TYPE_CHECKING: from dvc_data.hashfile.obj import HashFile +def posixpath_to_os_path(path: str) -> str: + return path.replace(posixpath.sep, os.path.sep) + + def _in_cache(obj: "HashInfo", cache: "HashFileDB") -> bool: from dvc_objects.errors import ObjectFormatError @@ -213,6 +219,8 @@ def _diff_head_to_index( continue root = str(out) + if isinstance(out.fs, GitFileSystem): + root = posixpath_to_os_path(root) typ = "index" if rev == "workspace" else head objs[root][typ] = (out.get_obj(), out.hash_info) diff --git a/tests/func/test_data_status.py b/tests/func/test_data_status.py index 7d5d5f016..484b472eb 100644 --- a/tests/func/test_data_status.py +++ b/tests/func/test_data_status.py @@ -1,3 +1,4 @@ +from os import fspath from os.path import join import pytest @@ -99,6 +100,37 @@ def test_directory(M, tmp_dir, dvc, scm): } +def test_tracked_directory_deep(M, tmp_dir, dvc, scm): + """Test for a directory not in cwd, but nested inside other directories.""" + (tmp_dir / "sub").gen({"dir": {"foo": "foo"}}) + dvc.add(fspath(tmp_dir / "sub" / "dir")) + scm.add_commit(["sub/dir.dvc", "sub/.gitignore"], message="add sub/dir") + + (tmp_dir / "sub" / "dir").gen("bar", "bar") + dvc.commit(None, force=True) + (tmp_dir / "sub" / "dir").gen("foobar", "foobar") + + assert dvc.data_status() == { + **EMPTY_STATUS, + "committed": {"modified": [join("sub", "dir", "")]}, + "uncommitted": {"modified": [join("sub", "dir", "")]}, + "git": M.dict(), + } + assert dvc.data_status(granular=True, untracked_files="all") == { + **EMPTY_STATUS, + "committed": { + "added": [join("sub", "dir", "bar")], + "modified": [join("sub", "dir", "")], + }, + "uncommitted": { + "added": [join("sub", "dir", "foobar")], + "modified": [join("sub", "dir", "")], + }, + "git": M.dict(), + "unchanged": [join("sub", "dir", "foo")], + } + + def test_new_empty_git_repo(M, tmp_dir, scm): dvc = Repo.init() assert dvc.data_status() == {