Skip to content

dvc diff <rev> reports all-deleted/0-added for outputs after splitting a single-dir .dvc into per-subfolder .dvc files (3.66.1) #11050

Description

@JohnAtl

Description

After refactoring a single dir-output .dvc (e.g. review.dvc tracking
review/) into multiple sub-folder .dvc files (review/<name>.dvc,
each with path: <name> relative to its parent), dvc diff HEAD
(i.e. HEAD vs workspace) reports every file under the refactored
subtree as deleted, with 0 added and 0 modified, even though:

  • dvc status reports the workspace fully in sync.
  • The files all exist on disk at the expected paths.
  • The dir-hash .dir cache files referenced by each new .dvc are
    present and enumerate correctly.
  • HEAD's .dvc files are byte-identical to workspace's .dvc files
    (git status clean).
  • dvc diff HEAD HEAD (rev-to-rev) is correctly empty.
  • dvc diff HEAD~1 HEAD (other rev-to-rev pairings) work correctly.
  • dvc diff HEAD --targets <unaffected-subtree> works correctly.

The zero-added/zero-modified counts suggest the workspace-side
enumeration is returning an empty file list for the refactored
outputs, while the HEAD-side enumeration correctly expands the dir
caches; the diff then attributes all HEAD-side files to "deleted."

Reproduction

Pre-refactor state:

project/
  review.dvc            # outs: [{path: review, md5: <dir-hash>}]
  review/
    after_cma_phase1/
    clinician_files/
    ...

Refactor (each commit does one):

# Remove the umbrella tracker, leaving files in place
dvc remove review.dvc
git rm review.dvc

# Track each subfolder individually
dvc add review/after_cma_phase1
dvc add review/clinician_files
dvc add review/edf_files
# ...
git add review/*.dvc
git commit

Each new review/<name>.dvc looks like:

```yaml
outs:

  • md5: 69c24de62577c8e011842eaaa013ffc6.dir
    size: 1195692789
    nfiles: 140
    hash: md5
    path: after_cma_phase1
    ```

Then:

```bash
$ dvc status
Data and pipelines are up to date.

$ dvc diff HEAD HEAD

(empty, as expected)

$ dvc diff HEAD HEAD~1

(correct diff for the actual rev-to-rev change)

$ dvc diff HEAD --json | jq '{added, deleted, modified} | map_values(length)'
{ "added": 0, "deleted": 11957, "modified": 0 }
```

All 11,957 "deleted" paths still exist on disk and are correctly
listed inside their respective .dir cache files.

Things tried that did not help

  • dvc commit -f (no-op since dvc status is clean).
  • Running dvc diff HEAD from the subdirectory containing the
    refactored .dvc files.
  • Verifying every .dir cache file for each new sub-folder .dvc
    is present and well-formed.

Workarounds

  • dvc status for sync checks (authoritative; not affected).
  • Use commit-to-commit dvc diff <rev1> <rev2> (not affected).
  • Scope HEAD-vs-workspace diffs to unaffected targets:
    dvc diff HEAD --targets <other-target> (not affected).

Expected behavior

dvc diff HEAD with no workspace changes should report an empty
diff, matching dvc status.

Environment

```
DVC version: 3.66.1 (brew)
CPython 3.14.2
Linux 6.18.28-1-lts (x86_64)
glibc 2.43
```

Repo layout: monorepo, DVC project lives in a subdirectory of the
git repo (git toplevel and DVC root are not the same path). Remote:
local FS path remote.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions