diff --git a/dvc/repo/__init__.py b/dvc/repo/__init__.py
index ac55cb255..24ad3ea00 100644
--- a/dvc/repo/__init__.py
+++ b/dvc/repo/__init__.py
@@ -1,6 +1,7 @@
 from __future__ import unicode_literals
 
 import os
+
 import dvc.prompt as prompt
 import dvc.logger as logger
 
@@ -38,7 +39,7 @@ class Repo(object):
         from dvc.data_cloud import DataCloud
         from dvc.updater import Updater
         from dvc.repo.metrics import Metrics
-        from dvc.repo.tree import WorkingTree
+        from dvc.scm.tree import WorkingTree
 
         root_dir = self.find_root(root_dir)
 
diff --git a/dvc/repo/add.py b/dvc/repo/add.py
index 2a7182b75..af1234ff7 100644
--- a/dvc/repo/add.py
+++ b/dvc/repo/add.py
@@ -1,6 +1,6 @@
 import os
 
-from dvc.scm import scm_context
+from dvc.repo.scm_context import scm_context
 from dvc.stage import Stage
 from dvc.utils import walk_files
 from dvc.exceptions import RecursiveAddingWhileUsingFilename
diff --git a/dvc/repo/brancher.py b/dvc/repo/brancher.py
index 6a4cfca13..bc4f3e38a 100644
--- a/dvc/repo/brancher.py
+++ b/dvc/repo/brancher.py
@@ -25,7 +25,7 @@ def brancher(  # noqa: E302
     scm = self.scm
 
     if self.scm.is_dirty():
-        from dvc.repo.tree import WorkingTree
+        from dvc.scm.tree import WorkingTree
 
         self.tree = WorkingTree()
         yield "Working Tree"
diff --git a/dvc/repo/imp.py b/dvc/repo/imp.py
index fc4c2acdf..e317eb008 100644
--- a/dvc/repo/imp.py
+++ b/dvc/repo/imp.py
@@ -1,4 +1,4 @@
-from dvc.scm import scm_context
+from dvc.repo.scm_context import scm_context
 
 
 @scm_context
diff --git a/dvc/repo/move.py b/dvc/repo/move.py
index 360532ed9..9240880a7 100644
--- a/dvc/repo/move.py
+++ b/dvc/repo/move.py
@@ -1,7 +1,7 @@
 import os
 
 from dvc.exceptions import MoveNotDataSourceError
-from dvc.scm import scm_context
+from dvc.repo.scm_context import scm_context
 
 
 def _expand_target_path(from_path, to_path):
diff --git a/dvc/repo/reproduce.py b/dvc/repo/reproduce.py
index 762af2275..83b1f85e4 100644
--- a/dvc/repo/reproduce.py
+++ b/dvc/repo/reproduce.py
@@ -4,7 +4,7 @@ import os
 
 import dvc.logger as logger
 from dvc.exceptions import ReproductionError
-from dvc.scm import scm_context
+from dvc.repo.scm_context import scm_context
 
 
 def _reproduce_stage(stages, node, force, dry, interactive, no_commit):
diff --git a/dvc/repo/run.py b/dvc/repo/run.py
index 889310dfb..24cc8283d 100644
--- a/dvc/repo/run.py
+++ b/dvc/repo/run.py
@@ -1,6 +1,6 @@
 from __future__ import unicode_literals
 
-from dvc.scm import scm_context
+from dvc.repo.scm_context import scm_context
 
 
 @scm_context
diff --git a/dvc/repo/scm_context.py b/dvc/repo/scm_context.py
new file mode 100644
index 000000000..583a8b3f8
--- /dev/null
+++ b/dvc/repo/scm_context.py
@@ -0,0 +1,12 @@
+def scm_context(method):
+    def run(repo, *args, **kw):
+        try:
+            result = method(repo, *args, **kw)
+            repo.scm.reset_ignores()
+            repo.scm.remind_to_track()
+            return result
+        except Exception as e:
+            repo.scm.cleanup_ignores()
+            raise e
+
+    return run
diff --git a/dvc/scm/__init__.py b/dvc/scm/__init__.py
index c5f8d20d7..5a6347fb3 100644
--- a/dvc/scm/__init__.py
+++ b/dvc/scm/__init__.py
@@ -5,8 +5,6 @@ from __future__ import unicode_literals
 from dvc.scm.base import Base
 from dvc.scm.git import Git
 
-import dvc
-
 
 # just a sugar to point that this is an actual implementation for a dvc
 # project under no SCM control
@@ -29,19 +27,3 @@ def SCM(root_dir, repo=None):  # pylint: disable=invalid-name
         return Git(root_dir, repo=repo)
 
     return NoSCM(root_dir, repo=repo)
-
-
-def scm_context(method):
-    def run(*args, **kw):
-        repo = args[0]
-        assert isinstance(repo, dvc.repo.Repo)
-        try:
-            result = method(*args, **kw)
-            repo.scm.reset_ignores()
-            repo.scm.remind_to_track()
-            return result
-        except Exception as e:
-            repo.scm.cleanup_ignores()
-            raise e
-
-    return run
diff --git a/dvc/scm/git/tree.py b/dvc/scm/git/tree.py
index d9c56293e..d6aff9151 100644
--- a/dvc/scm/git/tree.py
+++ b/dvc/scm/git/tree.py
@@ -3,7 +3,7 @@ import os
 
 from dvc.utils.compat import StringIO
 
-from dvc.repo.tree import BaseTree
+from dvc.scm.tree import BaseTree
 
 
 # see git-fast-import(1)

Cyclic import in dvc.scm.git.tree
#1709 dvc.scm.git.tree imports dvc.repo.tree, and this introduced a cyclic import which fires when `dvc.scm` is imported before `dvc.repo`:

### To reproduce

```
> python -c "import dvc.scm"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "dvc/scm/__init__.py", line 6, in <module>
    from dvc.scm.git import Git
  File "dvc/scm/git/__init__.py", line 15, in <module>
    from dvc.scm.git.tree import GitTree
  File "dvc/scm/git/tree.py", line 6, in <module>
    from dvc.repo.tree import BaseTree
  File "dvc/repo/__init__.py", line 10, in <module>
    class Repo(object):
  File "dvc/repo/__init__.py", line 15, in Repo
    from dvc.repo.add import add
  File "dvc/repo/add.py", line 3, in <module>
    from dvc.scm import scm_context
ImportError: cannot import name scm_context
```

diff --git a/dvc/repo/tree.py b/dvc/scm/tree.py
similarity index 100%
rename from dvc/repo/tree.py
rename to dvc/scm/tree.py
diff --git a/tests/test_repo.py b/tests/test_repo.py
index 0a99533af..aa3306301 100644
--- a/tests/test_repo.py
+++ b/tests/test_repo.py
@@ -1,7 +1,7 @@
 from tests.basic_env import TestDvc
 
 from dvc.scm.git import GitTree
-from dvc.repo.tree import WorkingTree
+from dvc.scm.tree import WorkingTree
 
 
 class TestCollect(TestDvc):
diff --git a/tests/test_tree.py b/tests/test_tree.py
index de81f8093..6f6ec1153 100644
--- a/tests/test_tree.py
+++ b/tests/test_tree.py
@@ -6,7 +6,7 @@ from os.path import join
 
 from dvc.scm import SCM
 from dvc.scm.git import GitTree
-from dvc.repo.tree import WorkingTree
+from dvc.scm.tree import WorkingTree
 
 from tests.basic_env import TestDir, TestGit
 
diff --git a/tests/unit/scm/test_scm.py b/tests/unit/scm/test_scm.py
index 4a7ede011..484c6f396 100644
--- a/tests/unit/scm/test_scm.py
+++ b/tests/unit/scm/test_scm.py
@@ -1,5 +1,6 @@
 from dvc.repo import Repo
-from dvc.scm import scm_context, NoSCM
+from dvc.repo.scm_context import scm_context
+from dvc.scm import NoSCM
 from unittest import TestCase
 import mock
 

pip install -e .[all]
parse_log_pytest
requirements.txt
pytest mock
apt-get update apt-get install -y gcc
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
altgraph==0.17.4
appdirs==1.4.4
asciimatics==1.15.0
azure-common==1.1.28
azure-nspkg==3.0.2
azure-storage-blob==1.3.0
azure-storage-common==1.3.0
azure-storage-nspkg==3.1.0
bcrypt==4.3.0
boto3==1.9.115
botocore==1.12.253
cachetools==5.5.2
certifi==2025.1.31
cffi==1.17.1
charset-normalizer==3.4.1
colorama==0.4.6
configobj==5.0.9
configparser==7.2.0
cryptography==44.0.2
decorator==5.2.1
distro==1.9.0
docutils==0.15.2
-e git+https://github.com/iterative/dvc.git@402eb2da0122932c0a8cd04cd1a9b88f6a0bc432#egg=dvc
exceptiongroup==1.2.2
future==1.0.0
gitdb==4.0.12
GitPython==3.1.44
google-api-core==1.34.1
google-auth==2.38.0
google-cloud-core==0.28.1
google-cloud-storage==1.13.0
google-crc32c==1.7.1
google-resumable-media==2.7.2
googleapis-common-protos==1.69.2
grandalf==0.6
idna==3.10
iniconfig==2.1.0
jmespath==0.10.0
jsonpath-rw==1.4.0
macholib==1.16.3
mock==5.2.0
nanotime==0.5.2
networkx==3.2.1
packaging==24.2
paramiko==3.5.1
pefile==2024.8.26
pillow==11.1.0
pluggy==1.5.0
ply==3.11
protobuf==3.20.3
pyasn1==0.6.1
pyasn1_modules==0.4.2
pycparser==2.22
pydot==3.0.4
pyfiglet==1.0.2
PyInstaller==3.3.1
PyNaCl==1.5.0
pyparsing==3.2.3
pytest==8.3.5
python-dateutil==2.9.0.post0
PyYAML==6.0.2
requests==2.32.3
rsa==4.9
s3transfer==0.2.1
schema==0.7.7
six==1.17.0
smmap==5.0.2
tomli==2.2.1
urllib3==1.25.11
wcwidth==0.2.13
zc.lockfile==3.0.post1

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
  - ca-certificates=2025.2.25=h06a4308_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=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - altgraph==0.17.4
      - appdirs==1.4.4
      - asciimatics==1.15.0
      - azure-common==1.1.28
      - azure-nspkg==3.0.2
      - azure-storage-blob==1.3.0
      - azure-storage-common==1.3.0
      - azure-storage-nspkg==3.1.0
      - bcrypt==4.3.0
      - boto3==1.9.115
      - botocore==1.12.253
      - cachetools==5.5.2
      - certifi==2025.1.31
      - cffi==1.17.1
      - charset-normalizer==3.4.1
      - colorama==0.4.6
      - configobj==5.0.9
      - configparser==7.2.0
      - cryptography==44.0.2
      - decorator==5.2.1
      - distro==1.9.0
      - docutils==0.15.2
      - dvc==0.32.1
      - exceptiongroup==1.2.2
      - future==1.0.0
      - gitdb==4.0.12
      - gitpython==3.1.44
      - google-api-core==1.34.1
      - google-auth==2.38.0
      - google-cloud-core==0.28.1
      - google-cloud-storage==1.13.0
      - google-crc32c==1.7.1
      - google-resumable-media==2.7.2
      - googleapis-common-protos==1.69.2
      - grandalf==0.6
      - idna==3.10
      - iniconfig==2.1.0
      - jmespath==0.10.0
      - jsonpath-rw==1.4.0
      - macholib==1.16.3
      - mock==5.2.0
      - nanotime==0.5.2
      - networkx==3.2.1
      - packaging==24.2
      - paramiko==3.5.1
      - pefile==2024.8.26
      - pillow==11.1.0
      - pluggy==1.5.0
      - ply==3.11
      - protobuf==3.20.3
      - pyasn1==0.6.1
      - pyasn1-modules==0.4.2
      - pycparser==2.22
      - pydot==3.0.4
      - pyfiglet==1.0.2
      - pyinstaller==3.3.1
      - pynacl==1.5.0
      - pyparsing==3.2.3
      - pytest==8.3.5
      - python-dateutil==2.9.0.post0
      - pyyaml==6.0.2
      - requests==2.32.3
      - rsa==4.9
      - s3transfer==0.2.1
      - schema==0.7.7
      - six==1.17.0
      - smmap==5.0.2
      - tomli==2.2.1
      - urllib3==1.25.11
      - wcwidth==0.2.13
      - zc-lockfile==3.0.post1
prefix: /opt/conda/envs/dvc

tests/test_tree.py::TestWorkingTree::test_exists tests/test_tree.py::TestWorkingTree::test_isdir tests/test_tree.py::TestWorkingTree::test_isfile tests/test_tree.py::TestWorkingTree::test_open tests/test_tree.py::TestGitTree::test_exists tests/test_tree.py::TestGitTree::test_isdir tests/test_tree.py::TestGitTree::test_isfile tests/test_tree.py::TestGitTree::test_open tests/test_tree.py::TestWalkInNoSCM::test tests/test_tree.py::TestWalkInNoSCM::test_subdir tests/test_tree.py::TestWalkInGit::test_branch tests/test_tree.py::TestWalkInGit::test_nobranch tests/unit/scm/test_scm.py::TestScmContext::test_should_successfully_perform_method tests/unit/scm/test_scm.py::TestScmContext::test_should_throw_and_cleanup
tests/test_repo.py::TestCollect::test
dvc/repo/move.py dvc/repo/run.py dvc/repo/imp.py dvc/repo/brancher.py dvc/scm/__init__.py dvc/scm/git/tree.py dvc/repo/reproduce.py dvc/repo/scm_context.py dvc/repo/add.py dvc/repo/__init__.py
dvc/repo/move.py dvc/repo/run.py dvc/repo/imp.py dvc/repo/brancher.py dvc/scm/__init__.py dvc/scm/git/tree.py dvc/repo/reproduce.py dvc/repo/scm_context.py dvc/repo/add.py dvc/repo/__init__.py