pared: @skshetry 
I have test with committing imported for that, though I am not sure whether we should include that:
This test checks a particular use case, which origin is more general - lack of proper `checksum_changed()` method.
On the other hand, I would assume that committing repository with imported repo is quite popular use case, so it makes sense to test it. I will re-add the test.
pared: @skshetry I created test
diff --git a/dvc/config.py b/dvc/config.py
index 3b083597a..00b450eab 100644
--- a/dvc/config.py
+++ b/dvc/config.py
@@ -249,7 +249,7 @@ class Config(dict):
             self.dvc_dir = os.path.abspath(os.path.realpath(dvc_dir))
 
         self.wtree = LocalRemoteTree(None, {"url": self.dvc_dir})
-        self.tree = tree.tree if tree else self.wtree
+        self.tree = tree or self.wtree
 
         self.load(validate=validate)
 
diff --git a/dvc/dependency/repo.py b/dvc/dependency/repo.py
index a4994b892..eb3c58b5c 100644
--- a/dvc/dependency/repo.py
+++ b/dvc/dependency/repo.py
@@ -98,3 +98,9 @@ class RepoDependency(LocalDependency):
 
         with self._make_repo(locked=False) as repo:
             self.def_repo[self.PARAM_REV_LOCK] = repo.get_rev()
+
+    def changed_checksum(self):
+        # From current repo point of view what describes RepoDependency is its
+        # origin project url and rev_lock, and it makes RepoDependency
+        # immutable, hence its impossible for checksum to change.
+        return False
diff --git a/dvc/ignore.py b/dvc/ignore.py
index 2ab78ea00..f72623295 100644
--- a/dvc/ignore.py
+++ b/dvc/ignore.py
@@ -3,14 +3,12 @@ import os
 import re
 from itertools import groupby
 
-from funcy import cached_property
 from pathspec.patterns import GitWildMatchPattern
 from pathspec.util import normalize_file
 from pygtrie import StringTrie
 
 from dvc.path_info import PathInfo
 from dvc.pathspec_math import merge_patterns
-from dvc.scm.tree import BaseTree
 from dvc.system import System
 from dvc.utils import relpath
 
@@ -162,6 +160,20 @@ class DvcIgnoreRepo(DvcIgnore):
         return dirs, files
 
 
+class DvcIgnoreFilterNoop:
+    def __init__(self, tree, root_dir):
+        pass
+
+    def __call__(self, root, dirs, files):
+        return dirs, files
+
+    def is_ignored_dir(self, _):
+        return False
+
+    def is_ignored_file(self, _):
+        return False
+
+
 class DvcIgnoreFilter:
     def __init__(self, tree, root_dir):
         self.tree = tree
@@ -190,118 +202,52 @@ class DvcIgnoreFilter:
 
         return dirs, files
 
+    def is_ignored_dir(self, path):
+        if not self._parents_exist(path):
+            return True
 
-class CleanTree(BaseTree):
-    def __init__(self, tree, tree_root=None):
-        self.tree = tree
-        if tree_root:
-            self._tree_root = tree_root
-        else:
-            self._tree_root = self.tree.tree_root
-
-    @cached_property
-    def dvcignore(self):
-        return DvcIgnoreFilter(self.tree, self.tree_root)
-
-    @property
-    def tree_root(self):
-        return self._tree_root
-
-    def open(self, path, mode="r", encoding="utf-8"):
-        if self.isfile(path):
-            return self.tree.open(path, mode, encoding)
-        raise FileNotFoundError
-
-    def exists(self, path):
-        if self.tree.exists(path) and self._parents_exist(path):
-            if self.tree.isdir(path):
-                return self._valid_dirname(path)
-            return self._valid_filename(path)
-        return False
-
-    def isdir(self, path):
-        return (
-            self.tree.isdir(path)
-            and self._parents_exist(path)
-            and self._valid_dirname(path)
-        )
-
-    def _valid_dirname(self, path):
         path = os.path.abspath(path)
-        if path == self.tree_root:
-            return True
+        if path == self.root_dir:
+            return False
         dirname, basename = os.path.split(path)
-        dirs, _ = self.dvcignore(dirname, [basename], [])
-        if dirs:
-            return True
-        return False
+        dirs, _ = self(dirname, [basename], [])
+        return not dirs
 
-    def isfile(self, path):
-        return (
-            self.tree.isfile(path)
-            and self._parents_exist(path)
-            and self._valid_filename(path)
-        )
-
-    def _valid_filename(self, path):
-        dirname, basename = os.path.split(os.path.normpath(path))
-        _, files = self.dvcignore(os.path.abspath(dirname), [], [basename])
-        if files:
+    def is_ignored_file(self, path):
+        if not self._parents_exist(path):
             return True
-        return False
 
-    def isexec(self, path):
-        return self.exists(path) and self.tree.isexec(path)
+        dirname, basename = os.path.split(os.path.normpath(path))
+        _, files = self(os.path.abspath(dirname), [], [basename])
+        return not files
 
     def _parents_exist(self, path):
         from dvc.repo import Repo
 
         path = PathInfo(path)
 
-        # if parent is tree_root or inside a .dvc dir we can skip this check
-        if path.parent == self.tree_root or Repo.DVC_DIR in path.parts:
+        # if parent is root_dir or inside a .dvc dir we can skip this check
+        if path.parent == self.root_dir or Repo.DVC_DIR in path.parts:
             return True
 
-        # paths outside of the CleanTree root should be ignored
-        path = relpath(path, self.tree_root)
+        # paths outside of the repo should be ignored
+        path = relpath(path, self.root_dir)
         if path.startswith("..") or (
             os.name == "nt"
             and not os.path.commonprefix(
-                [os.path.abspath(path), self.tree_root]
+                [os.path.abspath(path), self.root_dir]
             )
         ):
             return False
 
         # check if parent directories are in our ignores, starting from
-        # tree_root
+        # root_dir
         for parent_dir in reversed(PathInfo(path).parents):
             dirname, basename = os.path.split(parent_dir)
             if basename == ".":
-                # parent_dir == tree_root
+                # parent_dir == root_dir
                 continue
-            dirs, _ = self.dvcignore(os.path.abspath(dirname), [basename], [])
+            dirs, _ = self(os.path.abspath(dirname), [basename], [])
             if not dirs:
                 return False
         return True
-
-    def walk(self, top, topdown=True, onerror=None):
-        for root, dirs, files in self.tree.walk(
-            top, topdown=topdown, onerror=onerror
-        ):
-            dirs[:], files[:] = self.dvcignore(
-                os.path.abspath(root), dirs, files
-            )
-
-            yield root, dirs, files
-
-    def stat(self, path):
-        if self.exists(path):
-            return self.tree.stat(path)
-        raise FileNotFoundError
-
-    @property
-    def hash_jobs(self):
-        return self.tree.hash_jobs
-
-    def makedirs(self, path, mode=0o777, exist_ok=True):
-        self.tree.makedirs(path, mode=mode, exist_ok=exist_ok)
diff --git a/dvc/repo/__init__.py b/dvc/repo/__init__.py
index a1c3bc755..e8831881a 100644
--- a/dvc/repo/__init__.py
+++ b/dvc/repo/__init__.py
@@ -14,10 +14,8 @@ from dvc.exceptions import (
     NotDvcRepoError,
     OutputNotFoundError,
 )
-from dvc.ignore import CleanTree
 from dvc.path_info import PathInfo
 from dvc.repo.tree import RepoTree
-from dvc.scm.tree import is_working_tree
 from dvc.utils.fs import path_isin
 
 from ..stage.exceptions import StageFileDoesNotExistError, StageNotFound
@@ -85,12 +83,19 @@ class Repo:
             tree = scm.get_tree(rev)
             self.root_dir = self.find_root(root_dir, tree)
             self.scm = scm
-            self.tree = tree
+            self.tree = scm.get_tree(
+                rev, use_dvcignore=True, dvcignore_root=self.root_dir
+            )
             self.state = StateNoop()
         else:
             root_dir = self.find_root(root_dir)
             self.root_dir = os.path.abspath(os.path.realpath(root_dir))
-            self.tree = LocalRemoteTree(None, {"url": self.root_dir})
+            self.tree = LocalRemoteTree(
+                self,
+                {"url": self.root_dir},
+                use_dvcignore=True,
+                dvcignore_root=self.root_dir,
+            )
 
         self.dvc_dir = os.path.join(self.root_dir, self.DVC_DIR)
         self.config = Config(self.dvc_dir, tree=self.tree)
@@ -134,13 +139,7 @@ class Repo:
 
     @tree.setter
     def tree(self, tree):
-        if is_working_tree(tree) or tree.tree_root == self.root_dir:
-            root = None
-        else:
-            root = self.root_dir
-        self._tree = (
-            tree if isinstance(tree, CleanTree) else CleanTree(tree, root)
-        )
+        self._tree = tree
         # Our graph cache is no longer valid, as it was based on the previous
         # tree.
         self._reset()
@@ -605,4 +604,4 @@ class Repo:
         self.__dict__.pop("graph", None)
         self.__dict__.pop("stages", None)
         self.__dict__.pop("pipelines", None)
-        self.__dict__.pop("dvcignore", None)
+        self.tree.__dict__.pop("dvcignore", None)
diff --git a/dvc/repo/add.py b/dvc/repo/add.py
index 18983c6a9..dd1bf9594 100644
--- a/dvc/repo/add.py
+++ b/dvc/repo/add.py
@@ -109,17 +109,17 @@ def add(
 def _find_all_targets(repo, target, recursive):
     if os.path.isdir(target) and recursive:
         return [
-            fname
-            for fname in Tqdm(
+            os.fspath(path)
+            for path in Tqdm(
                 repo.tree.walk_files(target),
                 desc="Searching " + target,
                 bar_format=Tqdm.BAR_FMT_NOTOTAL,
                 unit="file",
             )
-            if not repo.is_dvc_internal(fname)
-            if not is_dvc_file(fname)
-            if not repo.scm.belongs_to_scm(fname)
-            if not repo.scm.is_tracked(fname)
+            if not repo.is_dvc_internal(os.fspath(path))
+            if not is_dvc_file(os.fspath(path))
+            if not repo.scm.belongs_to_scm(os.fspath(path))
+            if not repo.scm.is_tracked(os.fspath(path))
         ]
     return [target]
 
diff --git a/dvc/repo/brancher.py b/dvc/repo/brancher.py
index c42aa556c..0397b6e3c 100644
--- a/dvc/repo/brancher.py
+++ b/dvc/repo/brancher.py
@@ -29,7 +29,9 @@ def brancher(  # noqa: E302
 
     scm = self.scm
 
-    self.tree = LocalRemoteTree(self, {"url": self.root_dir})
+    self.tree = LocalRemoteTree(
+        self, {"url": self.root_dir}, use_dvcignore=True
+    )
     yield "workspace"
 
     if revs and "workspace" in revs:
@@ -47,7 +49,9 @@ def brancher(  # noqa: E302
     try:
         if revs:
             for sha, names in group_by(scm.resolve_rev, revs).items():
-                self.tree = scm.get_tree(sha)
+                self.tree = scm.get_tree(
+                    sha, use_dvcignore=True, dvcignore_root=self.root_dir
+                )
                 # ignore revs that don't contain repo root
                 # (i.e. revs from before a subdir=True repo was init'ed)
                 if self.tree.exists(self.root_dir):
diff --git a/dvc/scm/git/__init__.py b/dvc/scm/git/__init__.py
index 8056d4177..a78ee59a5 100644
--- a/dvc/scm/git/__init__.py
+++ b/dvc/scm/git/__init__.py
@@ -375,8 +375,8 @@ class Git(Base):
         path_parts = os.path.normpath(path).split(os.path.sep)
         return basename == self.ignore_file or Git.GIT_DIR in path_parts
 
-    def get_tree(self, rev):
-        return GitTree(self.repo, self.resolve_rev(rev))
+    def get_tree(self, rev, **kwargs):
+        return GitTree(self.repo, self.resolve_rev(rev), **kwargs)
 
     def get_rev(self):
         return self.repo.rev_parse("HEAD").hexsha
diff --git a/dvc/scm/git/tree.py b/dvc/scm/git/tree.py
index 0793d3d04..158ae2d91 100644
--- a/dvc/scm/git/tree.py
+++ b/dvc/scm/git/tree.py
@@ -3,6 +3,8 @@ import io
 import os
 import stat
 
+from funcy import cached_property
+
 from dvc.exceptions import DvcException
 from dvc.scm.tree import BaseTree
 from dvc.utils import relpath
@@ -22,7 +24,7 @@ def _item_basename(item):
 class GitTree(BaseTree):  # pylint:disable=abstract-method
     """Proxies the repo file access methods to Git objects"""
 
-    def __init__(self, git, rev):
+    def __init__(self, git, rev, use_dvcignore=False, dvcignore_root=None):
         """Create GitTree instance
 
         Args:
@@ -31,11 +33,25 @@ class GitTree(BaseTree):  # pylint:disable=abstract-method
         """
         self.git = git
         self.rev = rev
+        self.use_dvcignore = use_dvcignore
+        self.dvcignore_root = dvcignore_root
 
     @property
     def tree_root(self):
         return self.git.working_dir
 
+    @cached_property
+    def dvcignore(self):
+        from dvc.ignore import DvcIgnoreFilter, DvcIgnoreFilterNoop
+
+        root = self.dvcignore_root or self.tree_root
+        if not self.use_dvcignore:
+            return DvcIgnoreFilterNoop(self, root)
+        self.use_dvcignore = False
+        ret = DvcIgnoreFilter(self, root)
+        self.use_dvcignore = True
+        return ret
+
     def open(self, path, mode="r", encoding="utf-8"):
         assert mode in {"r", "rb"}
 
@@ -58,20 +74,29 @@ class GitTree(BaseTree):  # pylint:disable=abstract-method
         return io.StringIO(data.decode(encoding))
 
     def exists(self, path):
-        return self._git_object_by_path(path) is not None
+        if self._git_object_by_path(path) is None:
+            return False
+
+        return not self.dvcignore.is_ignored_file(
+            path
+        ) and not self.dvcignore.is_ignored_dir(path)
 
     def isdir(self, path):
         obj = self._git_object_by_path(path)
         if obj is None:
             return False
-        return obj.mode == GIT_MODE_DIR
+        if obj.mode != GIT_MODE_DIR:
+            return False
+        return not self.dvcignore.is_ignored_dir(path)
 
     def isfile(self, path):
         obj = self._git_object_by_path(path)
         if obj is None:
             return False
         # according to git-fast-import(1) file mode could be 644 or 755
-        return obj.mode & GIT_MODE_FILE == GIT_MODE_FILE
+        if obj.mode & GIT_MODE_FILE != GIT_MODE_FILE:
+            return False
+        return not self.dvcignore.is_ignored_file(path)
 
     @staticmethod
     def _is_tree_and_contains(obj, path):
@@ -145,7 +170,11 @@ class GitTree(BaseTree):  # pylint:disable=abstract-method
                 onerror(NotADirectoryError(top))
             return
 
-        yield from self._walk(tree, topdown=topdown)
+        for root, dirs, files in self._walk(tree, topdown=topdown):
+            dirs[:], files[:] = self.dvcignore(
+                os.path.abspath(root), dirs, files
+            )
+            yield root, dirs, files
 
     def isexec(self, path):
         if not self.exists(path):
diff --git a/dvc/state.py b/dvc/state.py
index 7c41bb01e..f46dbe4e4 100644
--- a/dvc/state.py
+++ b/dvc/state.py
@@ -94,7 +94,7 @@ class State:  # pylint: disable=too-many-instance-attributes
         repo = local_cache.repo
         self.repo = repo
         self.root_dir = repo.root_dir
-        self.tree = LocalRemoteTree(None, {})
+        self.tree = LocalRemoteTree(None, {"url": self.root_dir})
 
         state_config = repo.config.get("state", {})
         self.row_limit = state_config.get("row_limit", self.STATE_ROW_LIMIT)
diff --git a/dvc/tree/base.py b/dvc/tree/base.py
index 8fc0791e1..18a2162d5 100644
--- a/dvc/tree/base.py
+++ b/dvc/tree/base.py
@@ -8,6 +8,8 @@ from multiprocessing import cpu_count
 from operator import itemgetter
 from urllib.parse import urlparse
 
+from funcy import cached_property
+
 from dvc.exceptions import (
     DvcException,
     DvcIgnoreInCollectedDirError,
@@ -86,13 +88,16 @@ class BaseRemoteTree:
         shared = config.get("shared")
         self._file_mode, self._dir_mode = self.SHARED_MODE_MAP[shared]
 
-        self.hash_jobs = (
-            config.get("hash_jobs")
+        self.verify = config.get("verify", self.DEFAULT_VERIFY)
+        self.path_info = None
+
+    @cached_property
+    def hash_jobs(self):
+        return (
+            self.config.get("hash_jobs")
             or (self.repo and self.repo.config["core"].get("hash_jobs"))
             or self.HASH_JOBS
         )
-        self.verify = config.get("verify", self.DEFAULT_VERIFY)
-        self.path_info = None
 
     @classmethod
     def get_missing_deps(cls):
@@ -245,7 +250,9 @@ class BaseRemoteTree:
         return hash_.endswith(cls.CHECKSUM_DIR_SUFFIX)
 
     def get_hash(self, path_info, tree=None, **kwargs):
-        assert isinstance(path_info, str) or path_info.scheme == self.scheme
+        assert path_info and (
+            isinstance(path_info, str) or path_info.scheme == self.scheme
+        )
 
         if not tree:
             tree = self
diff --git a/dvc/tree/local.py b/dvc/tree/local.py
index 6ddcf913a..201aecdbe 100644
--- a/dvc/tree/local.py
+++ b/dvc/tree/local.py
@@ -3,6 +3,7 @@ import logging
 import os
 import stat
 
+from funcy import cached_property
 from shortuuid import uuid
 
 from dvc.exceptions import DvcException
@@ -35,10 +36,12 @@ class LocalRemoteTree(BaseRemoteTree):
     CACHE_MODE = 0o444
     SHARED_MODE_MAP = {None: (0o644, 0o755), "group": (0o664, 0o775)}
 
-    def __init__(self, repo, config):
+    def __init__(self, repo, config, use_dvcignore=False, dvcignore_root=None):
         super().__init__(repo, config)
         url = config.get("url")
         self.path_info = self.PATH_CLS(url) if url else None
+        self.use_dvcignore = use_dvcignore
+        self.dvcignore_root = dvcignore_root
 
     @property
     def tree_root(self):
@@ -50,25 +53,46 @@ class LocalRemoteTree(BaseRemoteTree):
 
         return self.repo.state if self.repo else StateNoop()
 
+    @cached_property
+    def dvcignore(self):
+        from dvc.ignore import DvcIgnoreFilter, DvcIgnoreFilterNoop
+
+        root = self.dvcignore_root or self.tree_root
+        if not self.use_dvcignore:
+            return DvcIgnoreFilterNoop(self, root)
+        self.use_dvcignore = False
+        ret = DvcIgnoreFilter(self, root)
+        self.use_dvcignore = True
+        return ret
+
     @staticmethod
     def open(path_info, mode="r", encoding=None):
         return open(path_info, mode=mode, encoding=encoding)
 
     def exists(self, path_info):
         assert isinstance(path_info, str) or path_info.scheme == "local"
-        if not self.repo:
-            return os.path.exists(path_info)
-        return os.path.lexists(path_info)
+        if self.repo:
+            ret = os.path.lexists(path_info)
+        else:
+            ret = os.path.exists(path_info)
+        if not ret:
+            return False
+
+        return not self.dvcignore.is_ignored_file(
+            path_info
+        ) and not self.dvcignore.is_ignored_dir(path_info)
 
     def isfile(self, path_info):
-        if not self.repo:
-            return os.path.isfile(path_info)
-        return os.path.isfile(path_info)
+        if not os.path.isfile(path_info):
+            return False
+
+        return not self.dvcignore.is_ignored_file(path_info)
 
     def isdir(self, path_info):
-        if not self.repo:
-            return os.path.isdir(path_info)
-        return os.path.isdir(path_info)
+        if not os.path.isdir(path_info):
+            return False
+
+        return not self.dvcignore.is_ignored_dir(path_info)
 
     def iscopy(self, path_info):
         return not (
@@ -84,6 +108,10 @@ class LocalRemoteTree(BaseRemoteTree):
         for root, dirs, files in os.walk(
             top, topdown=topdown, onerror=onerror
         ):
+            dirs[:], files[:] = self.dvcignore(
+                os.path.abspath(root), dirs, files
+            )
+
             yield os.path.normpath(root), dirs, files
 
     def walk_files(self, path_info, **kwargs):
diff --git a/setup.py b/setup.py
index f0646c7a2..82ffe5f4e 100644
--- a/setup.py
+++ b/setup.py
@@ -71,7 +71,7 @@ install_requires = [
     "flufl.lock>=3.2,<4",
     "win-unicode-console>=0.5; sys_platform == 'win32'",
     "pywin32>=225; sys_platform == 'win32'",
-    "networkx>=2.1,<2.4",
+    "networkx>=2.1,<2.5",
     "pydot>=1.2.4",
     "speedcopy>=2.0.1; python_version < '3.8' and sys_platform == 'win32'",
     "flatten_json>=0.1.6",

`dvc commit` fails with files imported via `dvc import`
## Bug Report
Hello! I am importing some files in my main repo from another repo using the command `dvc import`.
Upon running `dvc commit` afterward, I get the following error (output of `dvc commit -v`):

```
2020-07-14 18:50:54,511 ERROR: unexpected error - 'NoneType' object has no attribute 'scheme'
------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/local/Cellar/dvc/1.1.10/libexec/lib/python3.8/site-packages/dvc/main.py", line 53, in main
    ret = cmd.run()
  File "/usr/local/Cellar/dvc/1.1.10/libexec/lib/python3.8/site-packages/dvc/command/commit.py", line 18, in run
    self.repo.commit(
  File "/usr/local/Cellar/dvc/1.1.10/libexec/lib/python3.8/site-packages/dvc/repo/__init__.py", line 36, in wrapper
    ret = f(repo, *args, **kwargs)
  File "/usr/local/Cellar/dvc/1.1.10/libexec/lib/python3.8/site-packages/dvc/repo/commit.py", line 42, in commit
    changes = stage.changed_entries()
  File "/usr/local/Cellar/dvc/1.1.10/libexec/lib/python3.8/site-packages/dvc/stage/__init__.py", line 405, in changed_entries
    changed_deps = self._changed_entries(self.deps)
  File "/usr/local/Cellar/dvc/1.1.10/libexec/lib/python3.8/site-packages/dvc/stage/__init__.py", line 399, in _changed_entries
    return [str(entry) for entry in entries if entry.changed_checksum()]
  File "/usr/local/Cellar/dvc/1.1.10/libexec/lib/python3.8/site-packages/dvc/stage/__init__.py", line 399, in <listcomp>
    return [str(entry) for entry in entries if entry.changed_checksum()]
  File "/usr/local/Cellar/dvc/1.1.10/libexec/lib/python3.8/site-packages/dvc/output/base.py", line 195, in changed_checksum
    return self.checksum != self.get_checksum()
  File "/usr/local/Cellar/dvc/1.1.10/libexec/lib/python3.8/site-packages/dvc/output/base.py", line 181, in get_checksum
    return self.remote.get_hash(self.path_info)
  File "/usr/local/Cellar/dvc/1.1.10/libexec/lib/python3.8/site-packages/dvc/remote/base.py", line 735, in get_hash
    return self.tree.get_hash(path_info, **kwargs)
  File "/usr/local/Cellar/dvc/1.1.10/libexec/lib/python3.8/site-packages/dvc/remote/base.py", line 276, in get_hash
    assert isinstance(path_info, str) or path_info.scheme == self.scheme
AttributeError: 'NoneType' object has no attribute 'scheme'
------------------------------------------------------------
```
If I perform `dvc add` on the files imported (effectively "pinning" them to the main repo) the error disappears and the command executes successfully.

As a workaround, adding the following lines before the `assert` statement in the function `get_hash()` in  `dvc/remote/base.py` gets rid of the error even for files imported via `dvc import`:
```
    def get_hash(self, path_info, tree=None, **kwargs):
        if not path_info:
            return None

        assert isinstance(path_info, str) or path_info.scheme == self.scheme
```
I never had any problem with DVC<1.0.0
My setup:
```
DVC version: 1.1.10
Python version: 3.8.3
Platform: macOS-10.14.6-x86_64-i386-64bit
Binary: False
Package: brew
Supported remotes: azure, gdrive, gs, http, https, s3, ssh, oss
Cache: reflink - supported, hardlink - supported, symlink - supported
Repo: dvc, git
```

diff --git a/tests/func/test_commit.py b/tests/func/test_commit.py
index 5e757d3b7..6c91abff3 100644
--- a/tests/func/test_commit.py
+++ b/tests/func/test_commit.py
@@ -1,3 +1,5 @@
+from os import fspath
+
 import pytest
 
 from dvc.dvcfile import PIPELINE_FILE
@@ -95,3 +97,13 @@ def test_commit_pipeline_stage(tmp_dir, dvc, run_copy):
     assert dvc.commit(f":{stage.addressing}") == [stage]
     assert dvc.commit(f"{PIPELINE_FILE}:{stage.addressing}") == [stage]
     assert dvc.commit(PIPELINE_FILE) == [stage]
+
+
+def test_imported_entries_unchanged(tmp_dir, dvc, erepo_dir):
+    with erepo_dir.chdir():
+        erepo_dir.dvc_gen("file", "file content", "initial commit")
+
+    stage = dvc.imp(fspath(erepo_dir), "file")
+
+    with dvc.state:
+        assert stage.changed_entries() == ([], [], None)
diff --git a/tests/func/test_ignore.py b/tests/func/test_ignore.py
index 31b66e047..7fb1e73b8 100644
--- a/tests/func/test_ignore.py
+++ b/tests/func/test_ignore.py
@@ -17,30 +17,33 @@ from dvc.tree.local import LocalRemoteTree
 from dvc.utils import relpath
 from dvc.utils.fs import get_mtime_and_size
 from tests.dir_helpers import TmpDir
-from tests.utils import to_posixpath
 
 
 def test_ignore(tmp_dir, dvc, monkeypatch):
     tmp_dir.gen({"dir": {"ignored": "text", "other": "text2"}})
     tmp_dir.gen(DvcIgnore.DVCIGNORE_FILE, "dir/ignored")
 
-    assert _files_set("dir", dvc.tree) == {"dir/other"}
+    dvc.tree.__dict__.pop("dvcignore", None)
 
-    monkeypatch.chdir("dir")
-    assert _files_set(".", dvc.tree) == {"./other"}
+    path = PathInfo(tmp_dir)
+
+    assert set(dvc.tree.walk_files(path / "dir")) == {path / "dir" / "other"}
 
 
 def test_ignore_unicode(tmp_dir, dvc):
     tmp_dir.gen({"dir": {"other": "text", "тест": "проверка"}})
     tmp_dir.gen(DvcIgnore.DVCIGNORE_FILE, "dir/тест")
-
-    assert _files_set("dir", dvc.tree) == {"dir/other"}
+    dvc.tree.__dict__.pop("dvcignore", None)
+    path = PathInfo(tmp_dir)
+    assert set(dvc.tree.walk_files(path / "dir")) == {path / "dir" / "other"}
 
 
 def test_rename_ignored_file(tmp_dir, dvc):
     tmp_dir.gen({"dir": {"ignored": "...", "other": "text"}})
 
     tmp_dir.gen(DvcIgnore.DVCIGNORE_FILE, "ignored*")
+    dvc.tree.__dict__.pop("dvcignore", None)
+
     mtime, size = get_mtime_and_size("dir", dvc.tree)
 
     shutil.move("dir/ignored", "dir/ignored_new")
@@ -62,6 +65,7 @@ def test_rename_file(tmp_dir, dvc):
 def test_remove_ignored_file(tmp_dir, dvc):
     tmp_dir.gen({"dir": {"ignored": "...", "other": "text"}})
     tmp_dir.gen(DvcIgnore.DVCIGNORE_FILE, "dir/ignored")
+    dvc.tree.__dict__.pop("dvcignore", None)
 
     mtime, size = get_mtime_and_size("dir", dvc.tree)
 
@@ -94,6 +98,7 @@ def test_ignore_collecting_dvcignores(tmp_dir, dvc, dname):
 
     top_ignore_file = (tmp_dir / dname).with_name(DvcIgnore.DVCIGNORE_FILE)
     top_ignore_file.write_text(os.path.basename(dname))
+    dvc.tree.__dict__.pop("dvcignore", None)
 
     ignore_file = tmp_dir / dname / DvcIgnore.DVCIGNORE_FILE
     ignore_file.write_text("foo")
@@ -125,17 +130,18 @@ def test_ignore_on_branch(tmp_dir, scm, dvc):
     with tmp_dir.branch("branch", new=True):
         tmp_dir.scm_gen(DvcIgnore.DVCIGNORE_FILE, "foo", commit="add ignore")
 
-    assert _files_set(".", dvc.tree) == {"./foo", "./bar"}
-
-    dvc.tree = scm.get_tree("branch")
-    assert _files_set(".", dvc.tree) == {
-        to_posixpath(os.path.join(dvc.root_dir, DvcIgnore.DVCIGNORE_FILE)),
-        to_posixpath(os.path.join(dvc.root_dir, "bar")),
+    dvc.tree.__dict__.pop("dvcignore", None)
+    path = PathInfo(tmp_dir)
+    assert set(dvc.tree.walk_files(path)) == {
+        path / "foo",
+        path / "bar",
     }
 
-
-def _files_set(root, tree):
-    return {to_posixpath(f) for f in tree.walk_files(root)}
+    dvc.tree = scm.get_tree("branch", use_dvcignore=True)
+    assert set(dvc.tree.walk_files(path)) == {
+        os.fspath(path / DvcIgnore.DVCIGNORE_FILE),
+        os.fspath(path / "bar"),
+    }
 
 
 def test_match_nested(tmp_dir, dvc):
@@ -147,7 +153,7 @@ def test_match_nested(tmp_dir, dvc):
             "dir": {"x.backup": "x backup", "tmp": "content"},
         }
     )
-
+    dvc.tree.__dict__.pop("dvcignore", None)
     result = {os.fspath(os.path.normpath(f)) for f in dvc.tree.walk_files(".")}
     assert result == {".dvcignore", "foo"}
 
@@ -165,6 +171,7 @@ def test_ignore_subrepo(tmp_dir, scm, dvc):
     tmp_dir.gen({".dvcignore": "foo", "subdir": {"foo": "foo"}})
     scm.add([".dvcignore"])
     scm.commit("init parent dvcignore")
+    dvc.tree.__dict__.pop("dvcignore", None)
 
     subrepo_dir = tmp_dir / "subdir"
     assert not dvc.tree.exists(PathInfo(subrepo_dir / "foo"))
@@ -181,8 +188,9 @@ def test_ignore_subrepo(tmp_dir, scm, dvc):
 def test_ignore_blank_line(tmp_dir, dvc):
     tmp_dir.gen({"dir": {"ignored": "text", "other": "text2"}})
     tmp_dir.gen(DvcIgnore.DVCIGNORE_FILE, "foo\n\ndir/ignored")
-
-    assert _files_set("dir", dvc.tree) == {"dir/other"}
+    dvc.tree.__dict__.pop("dvcignore", None)
+    path = PathInfo(tmp_dir)
+    assert set(dvc.tree.walk_files(path / "dir")) == {path / "dir" / "other"}
 
 
 # It is not possible to re-include a file if a parent directory of
@@ -196,7 +204,7 @@ def test_ignore_blank_line(tmp_dir, dvc):
         (
             {"dir": {"subdir": {"not_ignore": "121"}}},
             ["subdir/*", "!not_ignore"],
-            {"dir/subdir/not_ignore"},
+            {os.path.join("dir", "subdir", "not_ignore")},
         ),
         (
             {"dir": {"subdir": {"should_ignore": "121"}}},
@@ -215,7 +223,11 @@ def test_ignore_file_in_parent_path(
 ):
     tmp_dir.gen(data_struct)
     tmp_dir.gen(DvcIgnore.DVCIGNORE_FILE, "\n".join(pattern_list))
-    assert _files_set("dir", dvc.tree) == result_set
+    dvc.tree.__dict__.pop("dvcignore", None)
+    path = PathInfo(tmp_dir)
+    assert set(dvc.tree.walk_files(path / "dir")) == {
+        path / relpath for relpath in result_set
+    }
 
 
 # If there is a separator at the end of the pattern then the pattern
@@ -233,9 +245,12 @@ def test_ignore_sub_directory(tmp_dir, dvc):
         }
     )
     tmp_dir.gen({"dir": {DvcIgnore.DVCIGNORE_FILE: "doc/fortz"}})
-    assert _files_set("dir", dvc.tree) == {
-        "dir/a/doc/fortz/a",
-        "dir/{}".format(DvcIgnore.DVCIGNORE_FILE),
+
+    dvc.tree.__dict__.pop("dvcignore", None)
+    path = PathInfo(tmp_dir)
+    assert set(dvc.tree.walk_files(path / "dir")) == {
+        path / "dir" / "a" / "doc" / "fortz" / "a",
+        path / "dir" / DvcIgnore.DVCIGNORE_FILE,
     }
 
 
@@ -243,8 +258,10 @@ def test_ignore_sub_directory(tmp_dir, dvc):
 def test_ignore_directory(tmp_dir, dvc):
     tmp_dir.gen({"dir": {"fortz": {}, "a": {"fortz": {}}}})
     tmp_dir.gen({"dir": {DvcIgnore.DVCIGNORE_FILE: "fortz"}})
-    assert _files_set("dir", dvc.tree) == {
-        "dir/{}".format(DvcIgnore.DVCIGNORE_FILE),
+    dvc.tree.__dict__.pop("dvcignore", None)
+    path = PathInfo(tmp_dir)
+    assert set(dvc.tree.walk_files(path / "dir")) == {
+        path / "dir" / DvcIgnore.DVCIGNORE_FILE,
     }
 
 
@@ -252,10 +269,11 @@ def test_multi_ignore_file(tmp_dir, dvc, monkeypatch):
     tmp_dir.gen({"dir": {"subdir": {"should_ignore": "1", "not_ignore": "1"}}})
     tmp_dir.gen(DvcIgnore.DVCIGNORE_FILE, "dir/subdir/*_ignore")
     tmp_dir.gen({"dir": {DvcIgnore.DVCIGNORE_FILE: "!subdir/not_ignore"}})
-
-    assert _files_set("dir", dvc.tree) == {
-        "dir/subdir/not_ignore",
-        "dir/{}".format(DvcIgnore.DVCIGNORE_FILE),
+    dvc.tree.__dict__.pop("dvcignore", None)
+    path = PathInfo(tmp_dir)
+    assert set(dvc.tree.walk_files(path / "dir")) == {
+        path / "dir" / "subdir" / "not_ignore",
+        path / "dir" / DvcIgnore.DVCIGNORE_FILE,
     }
 
 
@@ -276,6 +294,7 @@ def test_pattern_trie_tree(tmp_dir, dvc):
             "other": {DvcIgnore.DVCIGNORE_FILE: "1\n2\n3"},
         }
     )
+    dvc.tree.__dict__.pop("dvcignore", None)
     ignore_pattern_trie = None
     for ignore in dvc.tree.dvcignore.ignores:
         if isinstance(ignore, DvcIgnorePatternsTrie):
diff --git a/tests/func/test_tree.py b/tests/func/test_tree.py
index f6e6d7021..9a533305c 100644
--- a/tests/func/test_tree.py
+++ b/tests/func/test_tree.py
@@ -1,7 +1,6 @@
 import os
 from os.path import join
 
-from dvc.ignore import CleanTree
 from dvc.path_info import PathInfo
 from dvc.repo import Repo
 from dvc.repo.tree import RepoTree
@@ -137,7 +136,9 @@ class TestWalkInNoSCM(AssertWalkEqualMixin, TestDir):
 
 class TestWalkInGit(AssertWalkEqualMixin, TestGit):
     def test_nobranch(self):
-        tree = CleanTree(LocalRemoteTree(None, {"url": self._root_dir}))
+        tree = LocalRemoteTree(
+            None, {"url": self._root_dir}, use_dvcignore=True
+        )
         self.assertWalkEqual(
             tree.walk("."),
             [
@@ -232,13 +233,13 @@ def test_cleantree_subrepo(tmp_dir, dvc, scm, monkeypatch):
 
     path = PathInfo(subrepo_dir)
 
-    assert isinstance(dvc.tree, CleanTree)
+    assert dvc.tree.use_dvcignore
     assert not dvc.tree.exists(path / "foo")
     assert not dvc.tree.isfile(path / "foo")
     assert not dvc.tree.exists(path / "dir")
     assert not dvc.tree.isdir(path / "dir")
 
-    assert isinstance(subrepo.tree, CleanTree)
+    assert subrepo.tree.use_dvcignore
     assert subrepo.tree.exists(path / "foo")
     assert subrepo.tree.isfile(path / "foo")
     assert subrepo.tree.exists(path / "dir")
diff --git a/tests/unit/utils/test_fs.py b/tests/unit/utils/test_fs.py
index c78e4a2a4..acae898b9 100644
--- a/tests/unit/utils/test_fs.py
+++ b/tests/unit/utils/test_fs.py
@@ -6,7 +6,6 @@ import pytest
 from mock import patch
 
 import dvc
-from dvc.ignore import CleanTree
 from dvc.path_info import PathInfo
 from dvc.system import System
 from dvc.tree.local import LocalRemoteTree
@@ -29,7 +28,9 @@ from tests.basic_env import TestDir
 
 class TestMtimeAndSize(TestDir):
     def test(self):
-        tree = CleanTree(LocalRemoteTree(None, {"url": self.root_dir}))
+        tree = LocalRemoteTree(
+            None, {"url": self.root_dir}, use_dvcignore=True
+        )
         file_time, file_size = get_mtime_and_size(self.DATA, tree)
         dir_time, dir_size = get_mtime_and_size(self.DATA_DIR, tree)
 
@@ -130,7 +131,9 @@ def test_path_object_and_str_are_valid_types_get_mtime_and_size(tmp_dir):
     tmp_dir.gen(
         {"dir": {"dir_file": "dir file content"}, "file": "file_content"}
     )
-    tree = CleanTree(LocalRemoteTree(None, {"url": os.fspath(tmp_dir)}))
+    tree = LocalRemoteTree(
+        None, {"url": os.fspath(tmp_dir)}, use_dvcignore=True
+    )
 
     time, size = get_mtime_and_size("dir", tree)
     object_time, object_size = get_mtime_and_size(PathInfo("dir"), tree)

pip install -e .[all]
parse_log_pytest
pytest
pytest pytest-cov pytest-xdist pytest-mock pytest-lazy-fixture flaky mock xmltodict awscli google-compute-engine Pygments collective.checkdocs flake8 psutil flake8-docstrings pydocstyle jaraco.windows mock-ssh-server moto rangehttpserver beautifulsoup4 flake8-bugbear flake8-comprehensions flake8-string-format pylint pylint-pytest pylint-plugin-utils wget filelock
apt-get update apt-get install -y gcc
3.7
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
aliyun-python-sdk-core==2.16.0
aliyun-python-sdk-core-v3==2.13.33
aliyun-python-sdk-kms==2.16.5
appdirs==1.4.4
argcomplete==3.1.2
astroid==2.15.8
atpublic==3.1.2
attrs @ file:///croot/attrs_1668696182826/work
autocommand==2.2.2
awscli==1.31.13
azure-common==1.1.28
azure-storage-blob==2.1.0
azure-storage-common==2.1.0
bcrypt==4.2.1
beautifulsoup4==4.13.3
boto==2.49.0
boto3==1.33.13
botocore==1.33.13
cachetools==4.2.4
certifi @ file:///croot/certifi_1671487769961/work/certifi
cffi==1.15.1
charset-normalizer==3.4.1
collective.checkdocs==0.2
colorama==0.4.4
configobj==5.0.9
coverage==7.2.7
crcmod==1.7
cryptography==44.0.2
decorator==5.1.1
dill==0.3.7
distro==1.9.0
docutils==0.16
dpath==2.2.0
-e git+https://github.com/iterative/dvc.git@33abc407a1b4ae6aef3e1e83afe39d57a01d8ec7#egg=dvc
execnet==2.0.2
filelock==3.12.2
flake8==5.0.4
flake8-bugbear==23.3.12
flake8-comprehensions==3.13.0
flake8-docstrings==1.7.0
flake8-string-format==0.3.0
flaky==3.8.1
flatten-json==0.1.14
flit_core @ file:///opt/conda/conda-bld/flit-core_1644941570762/work/source/flit_core
flufl.lock==3.2
funcy==2.0
future==1.0.0
gitdb==4.0.12
GitPython==3.1.44
google-api-core==2.10.2
google-api-python-client==2.166.0
google-auth==1.35.0
google-auth-httplib2==0.2.0
google-cloud-core==1.7.3
google-cloud-storage==1.19.0
google-compute-engine==2.8.13
google-crc32c==1.5.0
google-resumable-media==2.7.2
googleapis-common-protos==1.69.2
grandalf==0.6
httplib2==0.22.0
idna==3.10
importlib-metadata==4.2.0
importlib-resources==5.12.0
inflect==6.0.5
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
isort==5.11.5
jaraco.classes==3.2.3
jaraco.collections==4.2.0
jaraco.context==4.3.0
jaraco.functools==3.7.0
jaraco.structures==2.1.0
jaraco.text==3.11.1
jaraco.ui==2.3.0
jaraco.windows==5.7.0
Jinja2==3.1.6
jmespath==0.10.0
jsonpath-ng==1.7.0
knack==0.12.0
lazy-object-proxy==1.9.0
MarkupSafe==2.1.5
mccabe==0.7.0
mock==5.2.0
mock-ssh-server==0.9.1
more-itertools==9.1.0
moto==4.2.14
nanotime==0.5.2
networkx==2.3
numpy==1.21.6
oauth2client==4.1.3
oss2==2.6.1
packaging @ file:///croot/packaging_1671697413597/work
paramiko==3.5.1
path==16.6.0
pathspec==0.11.2
platformdirs==4.0.0
pluggy @ file:///tmp/build/80754af9/pluggy_1648042572264/work
ply==3.11
protobuf==4.24.4
psutil==7.0.0
py @ file:///opt/conda/conda-bld/py_1644396412707/work
pyarrow==12.0.1
pyasn1==0.5.1
pyasn1-modules==0.3.0
pycodestyle==2.9.1
pycparser==2.21
pycryptodome==3.22.0
pydantic==1.10.21
pydocstyle==6.3.0
pydot==2.0.0
PyDrive2==1.15.4
pyflakes==2.5.0
Pygments==2.17.2
pygtrie==2.3.2
pylint==2.17.7
pylint-plugin-utils==0.8.2
pylint-pytest==1.1.8
PyNaCl==1.5.0
pyOpenSSL==25.0.0
pyparsing==3.1.4
pytest==7.1.2
pytest-cov==4.1.0
pytest-lazy-fixture==0.6.3
pytest-mock==3.11.1
pytest-xdist==3.5.0
python-dateutil==2.9.0.post0
PyYAML==5.3.1
rangehttpserver==1.4.0
requests==2.31.0
responses==0.23.3
rsa==4.7.2
ruamel.yaml==0.18.10
ruamel.yaml.clib==0.2.8
s3transfer==0.8.2
shortuuid==1.0.13
shtab==1.7.1
six==1.17.0
smmap==5.0.2
snowballstemmer==2.2.0
soupsieve==2.4.1
tabulate==0.9.0
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work
tomlkit==0.12.5
tqdm==4.67.1
typed-ast==1.5.5
types-PyYAML==6.0.12.12
typing_extensions==4.7.1
uritemplate==4.1.1
urllib3==1.26.20
voluptuous==0.14.1
Werkzeug==2.2.3
wget==3.2
wrapt==1.16.0
xmltodict==0.14.2
zc.lockfile==3.0.post1
zipp @ file:///croot/zipp_1672387121353/work

name: dvc
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - attrs=22.1.0=py37h06a4308_0
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - flit-core=3.6.0=pyhd3eb1b0_0
  - importlib_metadata=4.11.3=hd3eb1b0_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - packaging=22.0=py37h06a4308_0
  - pip=22.3.1=py37h06a4308_0
  - pluggy=1.0.0=py37h06a4308_1
  - py=1.11.0=pyhd3eb1b0_0
  - pytest=7.1.2=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py37h06a4308_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zipp=3.11.0=py37h06a4308_0
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - aliyun-python-sdk-core==2.16.0
      - aliyun-python-sdk-core-v3==2.13.33
      - aliyun-python-sdk-kms==2.16.5
      - appdirs==1.4.4
      - argcomplete==3.1.2
      - astroid==2.15.8
      - atpublic==3.1.2
      - autocommand==2.2.2
      - awscli==1.31.13
      - azure-common==1.1.28
      - azure-storage-blob==2.1.0
      - azure-storage-common==2.1.0
      - bcrypt==4.2.1
      - beautifulsoup4==4.13.3
      - boto==2.49.0
      - boto3==1.33.13
      - botocore==1.33.13
      - cachetools==4.2.4
      - cffi==1.15.1
      - charset-normalizer==3.4.1
      - collective-checkdocs==0.2
      - colorama==0.4.4
      - configobj==5.0.9
      - coverage==7.2.7
      - crcmod==1.7
      - cryptography==44.0.2
      - decorator==5.1.1
      - dill==0.3.7
      - distro==1.9.0
      - docutils==0.16
      - dpath==2.2.0
      - dvc==1.1.10+33abc4
      - execnet==2.0.2
      - filelock==3.12.2
      - flake8==5.0.4
      - flake8-bugbear==23.3.12
      - flake8-comprehensions==3.13.0
      - flake8-docstrings==1.7.0
      - flake8-string-format==0.3.0
      - flaky==3.8.1
      - flatten-json==0.1.14
      - flufl-lock==3.2
      - funcy==2.0
      - future==1.0.0
      - gitdb==4.0.12
      - gitpython==3.1.44
      - google-api-core==2.10.2
      - google-api-python-client==2.166.0
      - google-auth==1.35.0
      - google-auth-httplib2==0.2.0
      - google-cloud-core==1.7.3
      - google-cloud-storage==1.19.0
      - google-compute-engine==2.8.13
      - google-crc32c==1.5.0
      - google-resumable-media==2.7.2
      - googleapis-common-protos==1.69.2
      - grandalf==0.6
      - httplib2==0.22.0
      - idna==3.10
      - importlib-metadata==4.2.0
      - importlib-resources==5.12.0
      - inflect==6.0.5
      - isort==5.11.5
      - jaraco-classes==3.2.3
      - jaraco-collections==4.2.0
      - jaraco-context==4.3.0
      - jaraco-functools==3.7.0
      - jaraco-structures==2.1.0
      - jaraco-text==3.11.1
      - jaraco-ui==2.3.0
      - jaraco-windows==5.7.0
      - jinja2==3.1.6
      - jmespath==0.10.0
      - jsonpath-ng==1.7.0
      - knack==0.12.0
      - lazy-object-proxy==1.9.0
      - markupsafe==2.1.5
      - mccabe==0.7.0
      - mock==5.2.0
      - mock-ssh-server==0.9.1
      - more-itertools==9.1.0
      - moto==4.2.14
      - nanotime==0.5.2
      - networkx==2.3
      - numpy==1.21.6
      - oauth2client==4.1.3
      - oss2==2.6.1
      - paramiko==3.5.1
      - path==16.6.0
      - pathspec==0.11.2
      - platformdirs==4.0.0
      - ply==3.11
      - protobuf==4.24.4
      - psutil==7.0.0
      - pyarrow==12.0.1
      - pyasn1==0.5.1
      - pyasn1-modules==0.3.0
      - pycodestyle==2.9.1
      - pycparser==2.21
      - pycryptodome==3.22.0
      - pydantic==1.10.21
      - pydocstyle==6.3.0
      - pydot==2.0.0
      - pydrive2==1.15.4
      - pyflakes==2.5.0
      - pygments==2.17.2
      - pygtrie==2.3.2
      - pylint==2.17.7
      - pylint-plugin-utils==0.8.2
      - pylint-pytest==1.1.8
      - pynacl==1.5.0
      - pyopenssl==25.0.0
      - pyparsing==3.1.4
      - pytest-cov==4.1.0
      - pytest-lazy-fixture==0.6.3
      - pytest-mock==3.11.1
      - pytest-xdist==3.5.0
      - python-dateutil==2.9.0.post0
      - pyyaml==5.3.1
      - rangehttpserver==1.4.0
      - requests==2.31.0
      - responses==0.23.3
      - rsa==4.7.2
      - ruamel-yaml==0.18.10
      - ruamel-yaml-clib==0.2.8
      - s3transfer==0.8.2
      - shortuuid==1.0.13
      - shtab==1.7.1
      - six==1.17.0
      - smmap==5.0.2
      - snowballstemmer==2.2.0
      - soupsieve==2.4.1
      - tabulate==0.9.0
      - tomlkit==0.12.5
      - tqdm==4.67.1
      - typed-ast==1.5.5
      - types-pyyaml==6.0.12.12
      - typing-extensions==4.7.1
      - uritemplate==4.1.1
      - urllib3==1.26.20
      - voluptuous==0.14.1
      - werkzeug==2.2.3
      - wget==3.2
      - wrapt==1.16.0
      - xmltodict==0.14.2
      - zc-lockfile==3.0.post1
prefix: /opt/conda/envs/dvc

tests/func/test_commit.py::test_imported_entries_unchanged tests/func/test_ignore.py::test_ignore tests/func/test_ignore.py::test_ignore_unicode tests/func/test_ignore.py::test_ignore_on_branch tests/func/test_ignore.py::test_ignore_external tests/func/test_ignore.py::test_ignore_file_in_parent_path[data_struct0-pattern_list0-result_set0] tests/func/test_ignore.py::test_ignore_sub_directory tests/func/test_ignore.py::test_ignore_directory tests/func/test_ignore.py::test_multi_ignore_file tests/func/test_tree.py::TestWalkInGit::test_nobranch tests/func/test_tree.py::test_cleantree_subrepo tests/unit/utils/test_fs.py::TestMtimeAndSize::test tests/unit/utils/test_fs.py::test_path_object_and_str_are_valid_types_get_mtime_and_size
tests/func/test_ignore.py::test_match_nested tests/func/test_ignore.py::test_ignore_blank_line tests/func/test_ignore.py::test_pattern_trie_tree
tests/func/test_commit.py::test_commit_recursive tests/func/test_commit.py::test_commit_force tests/func/test_commit.py::test_commit_with_deps[run_kw0] tests/func/test_commit.py::test_commit_with_deps[run_kw1] tests/func/test_commit.py::test_commit_changed_md5 tests/func/test_commit.py::test_commit_no_exec tests/func/test_commit.py::test_commit_pipeline_stage tests/func/test_ignore.py::test_rename_ignored_file tests/func/test_ignore.py::test_rename_file tests/func/test_ignore.py::test_remove_ignored_file tests/func/test_ignore.py::test_remove_file tests/func/test_ignore.py::test_dvcignore_in_out_dir tests/func/test_ignore.py::test_ignore_collecting_dvcignores[dir] tests/func/test_ignore.py::test_ignore_collecting_dvcignores[dir/subdir] tests/func/test_ignore.py::test_ignore_subrepo tests/func/test_ignore.py::test_ignore_file_in_parent_path[data_struct1-pattern_list1-result_set1] tests/func/test_ignore.py::test_ignore_file_in_parent_path[data_struct2-pattern_list2-result_set2] tests/func/test_tree.py::TestLocalRemoteTree::test_exists tests/func/test_tree.py::TestLocalRemoteTree::test_isdir tests/func/test_tree.py::TestLocalRemoteTree::test_isfile tests/func/test_tree.py::TestLocalRemoteTree::test_open tests/func/test_tree.py::TestGitTree::test_exists tests/func/test_tree.py::TestGitTree::test_isdir tests/func/test_tree.py::TestGitTree::test_isfile tests/func/test_tree.py::TestGitTree::test_open tests/func/test_tree.py::TestGitSubmoduleTree::test_exists tests/func/test_tree.py::TestGitSubmoduleTree::test_isdir tests/func/test_tree.py::TestGitSubmoduleTree::test_isfile tests/func/test_tree.py::TestGitSubmoduleTree::test_open tests/func/test_tree.py::TestWalkInNoSCM::test tests/func/test_tree.py::TestWalkInNoSCM::test_subdir tests/func/test_tree.py::TestWalkInGit::test_branch tests/func/test_tree.py::test_repotree_walk_fetch tests/func/test_tree.py::test_repotree_cache_save tests/unit/utils/test_fs.py::TestContainsLink::test_path_object_and_str_are_valid_arg_types tests/unit/utils/test_fs.py::TestContainsLink::test_should_raise_exception_on_base_path_not_in_path tests/unit/utils/test_fs.py::TestContainsLink::test_should_return_false_on_no_more_dirs_below_path tests/unit/utils/test_fs.py::TestContainsLink::test_should_return_false_on_path_eq_to_base_path tests/unit/utils/test_fs.py::TestContainsLink::test_should_return_false_when_base_path_is_symlink tests/unit/utils/test_fs.py::TestContainsLink::test_should_return_true_on_symlink_in_path tests/unit/utils/test_fs.py::test_should_call_recursive_on_no_condition_matched tests/unit/utils/test_fs.py::test_get_inode tests/unit/utils/test_fs.py::test_move tests/unit/utils/test_fs.py::test_remove tests/unit/utils/test_fs.py::test_path_isin_positive tests/unit/utils/test_fs.py::test_path_isin_on_same_path tests/unit/utils/test_fs.py::test_path_isin_on_common_substring_path tests/unit/utils/test_fs.py::test_path_isin_accepts_pathinfo tests/unit/utils/test_fs.py::test_path_isin_with_absolute_path tests/unit/utils/test_fs.py::test_makedirs tests/unit/utils/test_fs.py::test_copyfile[file] tests/unit/utils/test_fs.py::test_copyfile[dir] tests/unit/utils/test_fs.py::test_copy_fobj_to_file tests/unit/utils/test_fs.py::test_walk_files
dvc/config.py dvc/ignore.py dvc/scm/git/__init__.py dvc/repo/brancher.py dvc/tree/base.py setup.py dvc/state.py dvc/tree/local.py dvc/scm/git/tree.py dvc/repo/add.py dvc/repo/__init__.py dvc/dependency/repo.py
dvc/config.py dvc/ignore.py dvc/scm/git/__init__.py dvc/repo/brancher.py dvc/tree/base.py setup.py dvc/state.py dvc/tree/local.py dvc/scm/git/tree.py dvc/repo/add.py dvc/repo/__init__.py dvc/dependency/repo.py