Repository: iterative/dvc

Issue:
diff gets confused when the object is not in cache
```console
#! /usr/bin/env bash

cd "$(mktemp -d)"
git init && dvc init
mkdir data
for i in $(seq 10); do
  echo $i >> data/$i.txt
done

dvc add data
git add -A && git commit -m "initialize"
rm -rf .dvc/cache  # clear cache
dvc diff
```

#### Expected

That it shows some files are not in cache correctly.


#### Actual

```
Added:
    data/1.txt
    data/10.txt
    data/2.txt
    data/3.txt
    data/4.txt
    data/5.txt
    data/6.txt
    data/7.txt
    data/8.txt
    data/9.txt
```




Discussion:

Fix (patch):
diff --git a/dvc/repo/diff.py b/dvc/repo/diff.py
index 0f83efcef..72795a3e4 100644
--- a/dvc/repo/diff.py
+++ b/dvc/repo/diff.py
@@ -45,6 +45,10 @@ def _diff(old, new, data_keys, with_missing=False):
         with_renames=True,
         meta_cmp_key=meta_cmp_key,
         roots=data_keys,
+        # we need to get unknown and unchanged entries to tell whether
+        # the object is missing from the cache or not.
+        with_unknown=with_missing,
+        with_unchanged=with_missing,
     ):
         if (change.old and change.old.isdir and not change.old.hash_info) or (
             change.new and change.new.isdir and not change.new.hash_info


Test changes:
diff --git a/tests/func/test_diff.py b/tests/func/test_diff.py
index 32776761d..4e74939d7 100644
--- a/tests/func/test_diff.py
+++ b/tests/func/test_diff.py
@@ -265,12 +265,22 @@ def test_diff_no_cache(tmp_dir, scm, dvc):
 
     remove(dvc.cache.local.path)
 
-    # invalidate_dir_info to force cache loading
-    dvc.cache.local._dir_info = {}
+    diff = dvc.diff("v1")
+    assert diff["added"] == []
+    assert diff["deleted"] == []
+    assert first(diff["modified"])["path"] == os.path.join("dir", "")
+    assert diff["renamed"] == []
+    assert diff["not in cache"] == [
+        {
+            "hash": "61d9c7f006e1ae7138fec5e574676ee2.dir",
+            "path": os.path.join("dir", ""),
+        }
+    ]
 
     diff = dvc.diff("v1", "v2")
     assert diff["added"] == []
     assert diff["deleted"] == []
+    assert diff["renamed"] == []
     assert first(diff["modified"])["path"] == os.path.join("dir", "")
     assert diff["not in cache"] == []