fabiosantoscode: DeepSource is complaining about some unused arguments in tests. I suppose I don't want to clean them up at this point.
efiop: > DeepSource is complaining about some unused arguments in tests. I suppose I shouldn't clean them up at this point.

@fabiosantoscode Yep, take it as a heads-up from DS. In this case there are no actions you should take. :slightly_smiling_face: 
fabiosantoscode: @efiop I believe I've addressed the comments.

WRT the `clone_dir` argument and the lost optimization, I removed the argument, and instead of changing the clone target, I changed the Repo's cache to `tmp_dir` which is next to the place the `get` will drop the file at.
fabiosantoscode: Cool @efiop, I've reverted the code to just clone into `tmp_dir` and addressed the remaining comments :+1: 
efiop: > WRT the clone_dir argument and the lost optimization, I removed the argument, and instead of changing the clone target, I changed the Repo's cache to tmp_dir which is next to the place the get will drop the file at.

Sorry, not sure I follow. I see that you still pass tmp_path to cached_clone , instead of keeping it as it was before and only changing the cache dir.
fabiosantoscode: @efiop I wrote that before you pointed out that it was enough to just clone the repo to `tmp_dir`, do disregard it.
fabiosantoscode: @jorgeorpinel thanks for your suggestions, it reads a lot clearer now.

As per fixing #3077, sure, let's do it :)
fabiosantoscode: @jorgeorpinel the docs for import are now updated. Check them out and see if they make sense to you.

@efiop your comments have all been addressed, I believe.

And @restyled-io has closed its PR, since the code style is on par. I ran `black dvc` locally just to confirm.
fabiosantoscode: I'll update the docs when this is confirmed to be the final help text.
diff --git a/dvc/command/get.py b/dvc/command/get.py
index 9aba35c0d..22856f1c0 100644
--- a/dvc/command/get.py
+++ b/dvc/command/get.py
@@ -31,7 +31,9 @@ class CmdGet(CmdBaseNoRepo):
 
 
 def add_parser(subparsers, parent_parser):
-    GET_HELP = "Download/copy files or directories from DVC repository."
+    GET_HELP = (
+        "Download a file or directory from any DVC project or Git repository."
+    )
     get_parser = subparsers.add_parser(
         "get",
         parents=[parent_parser],
@@ -40,18 +42,17 @@ def add_parser(subparsers, parent_parser):
         formatter_class=argparse.RawDescriptionHelpFormatter,
     )
     get_parser.add_argument(
-        "url", help="URL of Git repository with DVC project to download from."
+        "url",
+        help="Location of DVC project or Git repository to download from",
     )
     get_parser.add_argument(
-        "path", help="Path to a file or directory within a DVC repository."
+        "path",
+        help="Path to a file or directory within the project or repository",
     )
     get_parser.add_argument(
-        "-o",
-        "--out",
-        nargs="?",
-        help="Destination path to copy/download files to.",
+        "-o", "--out", nargs="?", help="Destination path to download files to"
     )
     get_parser.add_argument(
-        "--rev", nargs="?", help="DVC repository git revision."
+        "--rev", nargs="?", help="Git revision (e.g. branch, tag, SHA)"
     )
     get_parser.set_defaults(func=CmdGet)
diff --git a/dvc/command/imp.py b/dvc/command/imp.py
index 9315f0374..2a8d515ff 100644
--- a/dvc/command/imp.py
+++ b/dvc/command/imp.py
@@ -30,7 +30,8 @@ class CmdImport(CmdBase):
 
 def add_parser(subparsers, parent_parser):
     IMPORT_HELP = (
-        "Download data from DVC repository and take it under DVC control."
+        "Download a file or directory from any DVC project or Git repository"
+        "and take it under DVC control."
     )
 
     import_parser = subparsers.add_parser(
@@ -41,15 +42,17 @@ def add_parser(subparsers, parent_parser):
         formatter_class=argparse.RawTextHelpFormatter,
     )
     import_parser.add_argument(
-        "url", help="URL of Git repository with DVC project to download from."
+        "url",
+        help="Location of DVC project or Git repository to download from",
     )
     import_parser.add_argument(
-        "path", help="Path to data within DVC repository."
+        "path",
+        help="Path to a file or directory within the project or repository",
     )
     import_parser.add_argument(
-        "-o", "--out", nargs="?", help="Destination path to put data to."
+        "-o", "--out", nargs="?", help="Destination path to download files to"
     )
     import_parser.add_argument(
-        "--rev", nargs="?", help="DVC repository git revision."
+        "--rev", nargs="?", help="Git revision (e.g. branch, tag, SHA)"
     )
     import_parser.set_defaults(func=CmdImport)
diff --git a/dvc/exceptions.py b/dvc/exceptions.py
index e48014e95..a551e35db 100644
--- a/dvc/exceptions.py
+++ b/dvc/exceptions.py
@@ -240,11 +240,6 @@ class DvcIgnoreInCollectedDirError(DvcException):
         )
 
 
-class UrlNotDvcRepoError(DvcException):
-    def __init__(self, url):
-        super().__init__("URL '{}' is not a dvc repository.".format(url))
-
-
 class GitHookAlreadyExistsError(DvcException):
     def __init__(self, hook_name):
         super().__init__(
diff --git a/dvc/repo/get.py b/dvc/repo/get.py
index 17607bbfa..3c417556c 100644
--- a/dvc/repo/get.py
+++ b/dvc/repo/get.py
@@ -7,10 +7,9 @@ from dvc.exceptions import (
     DvcException,
     NotDvcRepoError,
     OutputNotFoundError,
-    UrlNotDvcRepoError,
     PathMissingError,
 )
-from dvc.external_repo import external_repo
+from dvc.external_repo import external_repo, cached_clone
 from dvc.path_info import PathInfo
 from dvc.stage import Stage
 from dvc.utils import resolve_output
@@ -42,37 +41,47 @@ def get(url, path, out=None, rev=None):
     # and won't work with reflink/hardlink.
     dpath = os.path.dirname(os.path.abspath(out))
     tmp_dir = os.path.join(dpath, "." + str(shortuuid.uuid()))
+    repo_dir = None
     try:
-        with external_repo(cache_dir=tmp_dir, url=url, rev=rev) as repo:
-            # Try any links possible to avoid data duplication.
-            #
-            # Not using symlink, because we need to remove cache after we are
-            # done, and to make that work we would have to copy data over
-            # anyway before removing the cache, so we might just copy it
-            # right away.
-            #
-            # Also, we can't use theoretical "move" link type here, because
-            # the same cache file might be used a few times in a directory.
-            repo.cache.local.cache_types = ["reflink", "hardlink", "copy"]
-
-            try:
-                output = repo.find_out_by_relpath(path)
-            except OutputNotFoundError:
-                output = None
-
-            if output and output.use_cache:
-                _get_cached(repo, output, out)
-            else:
+        try:
+            with external_repo(cache_dir=tmp_dir, url=url, rev=rev) as repo:
+                # Try any links possible to avoid data duplication.
+                #
+                # Not using symlink, because we need to remove cache after we
+                # are done, and to make that work we would have to copy data
+                # over anyway before removing the cache, so we might just copy
+                # it right away.
+                #
+                # Also, we can't use theoretical "move" link type here, because
+                # the same cache file might be used a few times in a directory.
+                repo.cache.local.cache_types = ["reflink", "hardlink", "copy"]
+
+                try:
+                    output = repo.find_out_by_relpath(path)
+                except OutputNotFoundError:
+                    output = None
+
+                if output and output.use_cache:
+                    _get_cached(repo, output, out)
+                    return
+
                 # Either an uncached out with absolute path or a user error
-                if os.path.isabs(path):
-                    raise FileNotFoundError
 
-                fs_copy(os.path.join(repo.root_dir, path), out)
+                repo_dir = repo.root_dir
+
+        except NotDvcRepoError:
+            # Not a DVC repository, continue below and copy from git
+            pass
+
+        if os.path.isabs(path):
+            raise FileNotFoundError
+
+        if not repo_dir:
+            repo_dir = cached_clone(url, rev=rev)
 
+        fs_copy(os.path.join(repo_dir, path), out)
     except (OutputNotFoundError, FileNotFoundError):
         raise PathMissingError(path, url)
-    except NotDvcRepoError:
-        raise UrlNotDvcRepoError(url)
     finally:
         remove(tmp_dir)
 
diff --git a/dvc/scm/git/__init__.py b/dvc/scm/git/__init__.py
index 3872c8e72..7c432855e 100644
--- a/dvc/scm/git/__init__.py
+++ b/dvc/scm/git/__init__.py
@@ -229,8 +229,7 @@ class Git(Base):
         # it is equivalent to `bool(self.repo.git.ls_files(path))` by
         # functionality, but ls_files fails on unicode filenames
         path = relpath(path, self.root_dir)
-        # There are 4 stages, see BaseIndexEntry.stage
-        return any((path, i) in self.repo.index.entries for i in (0, 1, 2, 3))
+        return path in [i[0] for i in self.repo.index.entries]
 
     def is_dirty(self):
         return self.repo.is_dirty()

get: handle non-DVC repositories
Even though #2977 solved this for `dvc import`, it looks like it is still not supported for `dvc get`. It might be a simple bug or code path is different. We need to fix and add tests for this.

**Version**:
```
VC version: 0.80.0+82cdce
Python version: 3.7.5
Platform: Darwin-18.2.0-x86_64-i386-64bit
Binary: False
Package: None
Cache: reflink - True, hardlink - True, symlink - True
Filesystem type (cache directory): ('apfs', '/dev/disk1s1')
Filesystem type (workspace): ('apfs', '/dev/disk1s1') 
```

**Reproduce:**

```bash
mkdir git-repo
cd git-repo
git init
touch test
git commit -a -m "add test"
cd ..
dvc get ./git-repo test
 ```

outputs:

`ERROR: failed to get 'test' from './git-repo' - URL './git-repo' is not a dvc repository.`

diff --git a/tests/func/test_get.py b/tests/func/test_get.py
index cb2d05076..cdbbe4bbd 100644
--- a/tests/func/test_get.py
+++ b/tests/func/test_get.py
@@ -5,7 +5,6 @@ import pytest
 
 from dvc.cache import Cache
 from dvc.config import Config
-from dvc.exceptions import UrlNotDvcRepoError
 from dvc.repo.get import GetDVCFileError, PathMissingError
 from dvc.repo import Repo
 from dvc.system import System
@@ -87,9 +86,10 @@ def test_get_repo_rev(tmp_dir, erepo_dir):
 def test_get_from_non_dvc_repo(tmp_dir, erepo_dir):
     erepo_dir.scm.repo.index.remove([erepo_dir.dvc.dvc_dir], r=True)
     erepo_dir.scm.commit("remove dvc")
+    erepo_dir.scm_gen({"some_file": "contents"}, commit="create file")
 
-    with pytest.raises(UrlNotDvcRepoError):
-        Repo.get(fspath(erepo_dir), "some_file.zip")
+    Repo.get(fspath(erepo_dir), "some_file", "file_imported")
+    assert (tmp_dir / "file_imported").read_text() == "contents"
 
 
 def test_get_a_dvc_file(tmp_dir, erepo_dir):
@@ -136,6 +136,14 @@ def test_absolute_file_outside_repo(tmp_dir, erepo_dir):
         Repo.get(fspath(erepo_dir), "/root/")
 
 
+def test_absolute_file_outside_git_repo(tmp_dir, erepo_dir):
+    erepo_dir.scm.repo.index.remove([erepo_dir.dvc.dvc_dir], r=True)
+    erepo_dir.scm.commit("remove dvc")
+
+    with pytest.raises(PathMissingError):
+        Repo.get(fspath(erepo_dir), "/root/")
+
+
 def test_unknown_path(tmp_dir, erepo_dir):
     with pytest.raises(PathMissingError):
         Repo.get(fspath(erepo_dir), "a_non_existing_file")
@@ -164,10 +172,6 @@ def test_get_from_non_dvc_master(tmp_dir, erepo_dir, caplog):
         erepo_dir.dvc.scm.repo.index.remove([".dvc"], r=True)
         erepo_dir.dvc.scm.commit("remove .dvc")
 
-    # sanity check
-    with pytest.raises(UrlNotDvcRepoError):
-        Repo.get(fspath(erepo_dir), "some_file")
-
     caplog.clear()
     dst = "file_imported"
     with caplog.at_level(logging.INFO, logger="dvc"):
diff --git a/tests/func/test_repro.py b/tests/func/test_repro.py
index 4d9645743..e7ea6e735 100644
--- a/tests/func/test_repro.py
+++ b/tests/func/test_repro.py
@@ -2,10 +2,10 @@ import filecmp
 import getpass
 import os
 import posixpath
+import pathlib
 import re
 import shutil
 import uuid
-from pathlib import Path
 from subprocess import PIPE
 from subprocess import Popen
 from urllib.parse import urljoin
@@ -17,7 +17,6 @@ from flaky.flaky_decorator import flaky
 from google.cloud import storage as gc
 from mock import patch
 
-from dvc.compat import fspath
 from dvc.exceptions import CyclicGraphError
 from dvc.exceptions import ReproductionError
 from dvc.exceptions import StagePathAsOutputError
@@ -1373,190 +1372,210 @@ class TestShouldDisplayMetricsOnReproWithMetricsOption(TestDvc):
 
 
 @pytest.fixture
-def repro_dir(tmp_dir, dvc, run_copy):
-    # Creates repo with following structure:
-    #    data_dir/dir_file              origin_data
-    #         |       |                   |
-    #         |       |              origin_copy.dvc
-    # unrelated2.dvc  |               |       |
-    #                 |               |    unrelated1.dvc
-    #    dir/subdir/dir_file_copy.dvc |
-    #                  |              |
-    #                  |        dir/origin_copy_2.dvc
-    #                  |            |
-    #                   \          /
-    #                    \        /
-    #                   dir/Dvcfile
-    tmp_dir.gen(
-        {
-            "origin_data": "origin data content",
-            "data_dir": {"dir_file": "dir file content"},
-            "dir": {"subdir": {}},
-        }
+def repro_dir(dvc_repo, repo_dir):
+    repo_dir.dname = "dir"
+    os.mkdir(repo_dir.dname)
+    repo_dir.emptydname = "emptydir"
+    os.mkdir(repo_dir.emptydname)
+    subdname = os.path.join(repo_dir.dname, "subdir")
+    os.mkdir(subdname)
+
+    repo_dir.source = "source"
+    repo_dir.source_stage = repo_dir.source + ".dvc"
+    stage = dvc_repo.run(
+        fname=repo_dir.source_stage,
+        outs=[repo_dir.source],
+        deps=[repo_dir.FOO],
     )
-
-    stages = {}
-
-    origin_copy = tmp_dir / "origin_copy"
-    stage = run_copy("origin_data", fspath(origin_copy))
     assert stage is not None
-    assert origin_copy.read_text() == "origin data content"
-    stages["origin_copy"] = stage
-
-    origin_copy_2 = tmp_dir / "dir" / "origin_copy_2"
-    stage = run_copy(
-        fspath(origin_copy),
-        fspath(origin_copy_2),
-        fname=fspath(origin_copy_2) + ".dvc",
+    assert filecmp.cmp(repo_dir.source, repo_dir.FOO, shallow=False)
+
+    repo_dir.unrelated1 = "unrelated1"
+    repo_dir.unrelated1_stage = repo_dir.unrelated1 + ".dvc"
+    stage = dvc_repo.run(
+        fname=repo_dir.unrelated1_stage,
+        outs=[repo_dir.unrelated1],
+        deps=[repo_dir.source],
     )
     assert stage is not None
-    assert origin_copy_2.read_text() == "origin data content"
-    stages["origin_copy_2"] = stage
-
-    dir_file_path = tmp_dir / "data_dir" / "dir_file"
-    dir_file_copy = tmp_dir / "dir" / "subdir" / "dir_file_copy"
-    stage = run_copy(
-        fspath(dir_file_path),
-        fspath(dir_file_copy),
-        fname=fspath(dir_file_copy) + ".dvc",
-    )
-    assert stage is not None
-    assert dir_file_copy.read_text() == "dir file content"
-    stages["dir_file_copy"] = stage
 
-    last_stage = tmp_dir / "dir" / "Dvcfile"
-    stage = dvc.run(
-        fname=fspath(last_stage),
-        deps=[fspath(origin_copy_2), fspath(dir_file_copy)],
+    repo_dir.unrelated2 = "unrelated2"
+    repo_dir.unrelated2_stage = repo_dir.unrelated2 + ".dvc"
+    stage = dvc_repo.run(
+        fname=repo_dir.unrelated2_stage,
+        outs=[repo_dir.unrelated2],
+        deps=[repo_dir.DATA],
     )
     assert stage is not None
-    stages["last_stage"] = stage
-
-    # Unrelated are to verify that reproducing `dir` will not trigger them too
-    assert run_copy(fspath(origin_copy), "unrelated1") is not None
-    assert run_copy(fspath(dir_file_path), "unrelated2") is not None
-
-    yield stages
 
+    repo_dir.first = os.path.join(repo_dir.dname, "first")
+    repo_dir.first_stage = repo_dir.first + ".dvc"
 
-def _rewrite_file(path_elements, new_content):
-    if isinstance(path_elements, str):
-        path_elements = [path_elements]
-    file = Path(os.sep.join(path_elements))
-    file.unlink()
-    file.write_text(new_content)
+    stage = dvc_repo.run(
+        fname=repo_dir.first_stage,
+        deps=[repo_dir.source],
+        outs=[repo_dir.first],
+        cmd="python {} {} {}".format(
+            repo_dir.CODE, repo_dir.source, repo_dir.first
+        ),
+    )
+    assert stage is not None
+    assert filecmp.cmp(repo_dir.first, repo_dir.FOO, shallow=False)
+
+    repo_dir.second = os.path.join(subdname, "second")
+    repo_dir.second_stage = repo_dir.second + ".dvc"
+    stage = dvc_repo.run(
+        fname=repo_dir.second_stage,
+        outs=[repo_dir.second],
+        deps=[repo_dir.DATA],
+    )
+    assert stage is not None
+    assert filecmp.cmp(repo_dir.second, repo_dir.DATA, shallow=False)
 
+    repo_dir.third_stage = os.path.join(repo_dir.dname, "Dvcfile")
+    stage = dvc_repo.run(
+        fname=repo_dir.third_stage, deps=[repo_dir.first, repo_dir.second]
+    )
+    assert stage is not None
 
-def _read_out(stage):
-    return Path(stage.outs[0].fspath).read_text()
+    yield repo_dir
 
 
-def test_recursive_repro_default(dvc, repro_dir):
+def test_recursive_repro_default(dvc_repo, repro_dir):
     """
     Test recursive repro on dir after a dep outside this dir has changed.
     """
-    _rewrite_file("origin_data", "new origin data content")
+    os.unlink(repro_dir.FOO)
+    shutil.copyfile(repro_dir.BAR, repro_dir.FOO)
 
-    stages = dvc.reproduce("dir", recursive=True)
-
-    # Check that the dependency ("origin_copy") and the dependent stages
-    # inside the folder have been reproduced ("origin_copy_2", "last_stage")
-    assert stages == [
-        repro_dir["origin_copy"],
-        repro_dir["origin_copy_2"],
-        repro_dir["last_stage"],
-    ]
-    assert _read_out(repro_dir["origin_copy"]) == "new origin data content"
-    assert _read_out(repro_dir["origin_copy_2"]) == "new origin data content"
+    stages = dvc_repo.reproduce(repro_dir.dname, recursive=True)
+    # Check that the dependency ("source") and the dependent stages
+    # inside the folder have been reproduced ("first", "third")
+    assert len(stages) == 3
+    names = [stage.relpath for stage in stages]
+    assert repro_dir.source_stage in names
+    assert repro_dir.first_stage in names
+    assert repro_dir.third_stage in names
+    assert filecmp.cmp(repro_dir.source, repro_dir.BAR, shallow=False)
+    assert filecmp.cmp(repro_dir.first, repro_dir.BAR, shallow=False)
 
 
-def test_recursive_repro_single(dvc, repro_dir):
+def test_recursive_repro_single(dvc_repo, repro_dir):
     """
     Test recursive single-item repro on dir
     after a dep outside this dir has changed.
     """
-    _rewrite_file("origin_data", "new origin content")
-    _rewrite_file(["data_dir", "dir_file"], "new dir file content")
+    os.unlink(repro_dir.FOO)
+    shutil.copyfile(repro_dir.BAR, repro_dir.FOO)
 
-    stages = dvc.reproduce("dir", recursive=True, single_item=True)
+    os.unlink(repro_dir.DATA)
+    shutil.copyfile(repro_dir.BAR, repro_dir.DATA)
+
+    stages = dvc_repo.reproduce(
+        repro_dir.dname, recursive=True, single_item=True
+    )
     # Check that just stages inside given dir
     # with changed direct deps have been reproduced.
-    # This means that "origin_copy_2" stage should not be reproduced
-    # since it depends on "origin_copy".
-    # Also check that "dir_file_copy" stage was reproduced before "last_stage"
-    assert stages == [repro_dir["dir_file_copy"], repro_dir["last_stage"]]
-    assert _read_out(repro_dir["dir_file_copy"]) == "new dir file content"
+    # This means that "first" stage should not be reproduced
+    # since it depends on "source".
+    # Also check that "second" stage was reproduced before "third" stage
+    assert len(stages) == 2
+    assert repro_dir.second_stage == stages[0].relpath
+    assert repro_dir.third_stage == stages[1].relpath
+    assert filecmp.cmp(repro_dir.second, repro_dir.BAR, shallow=False)
 
 
-def test_recursive_repro_single_force(dvc, repro_dir):
+def test_recursive_repro_single_force(dvc_repo, repro_dir):
     """
     Test recursive single-item force repro on dir
     without any dependencies changing.
     """
-    stages = dvc.reproduce("dir", recursive=True, single_item=True, force=True)
-    # Check that all stages inside given dir have been reproduced
-    # Also check that "dir_file_copy" stage was reproduced before "last_stage"
-    # and that "origin_copy" stage was reproduced before "last_stage" stage
+    stages = dvc_repo.reproduce(
+        repro_dir.dname, recursive=True, single_item=True, force=True
+    )
     assert len(stages) == 3
-    assert set(stages) == {
-        repro_dir["origin_copy_2"],
-        repro_dir["dir_file_copy"],
-        repro_dir["last_stage"],
-    }
-    assert stages.index(repro_dir["origin_copy_2"]) < stages.index(
-        repro_dir["last_stage"]
+    names = [stage.relpath for stage in stages]
+    # Check that all stages inside given dir have been reproduced
+    # Also check that "second" stage was reproduced before "third" stage
+    # and that "first" stage was reproduced before "third" stage
+    assert repro_dir.first_stage in names
+    assert repro_dir.second_stage in names
+    assert repro_dir.third_stage in names
+    assert names.index(repro_dir.first_stage) < names.index(
+        repro_dir.third_stage
     )
-    assert stages.index(repro_dir["dir_file_copy"]) < stages.index(
-        repro_dir["last_stage"]
+    assert names.index(repro_dir.second_stage) < names.index(
+        repro_dir.third_stage
     )
 
 
-def test_recursive_repro_empty_dir(tmp_dir, dvc):
+def test_recursive_repro_empty_dir(dvc_repo, repro_dir):
     """
     Test recursive repro on an empty directory
     """
-    (tmp_dir / "emptydir").mkdir()
-
-    stages = dvc.reproduce("emptydir", recursive=True, force=True)
-    assert stages == []
+    stages = dvc_repo.reproduce(
+        repro_dir.emptydname, recursive=True, force=True
+    )
+    assert len(stages) == 0
 
 
-def test_recursive_repro_recursive_missing_file(dvc):
+def test_recursive_repro_recursive_missing_file(dvc_repo):
     """
     Test recursive repro on a missing file
     """
     with pytest.raises(StageFileDoesNotExistError):
-        dvc.reproduce("notExistingStage.dvc", recursive=True)
+        dvc_repo.reproduce("notExistingStage.dvc", recursive=True)
     with pytest.raises(StageFileDoesNotExistError):
-        dvc.reproduce("notExistingDir/", recursive=True)
+        dvc_repo.reproduce("notExistingDir/", recursive=True)
 
 
-def test_recursive_repro_on_stage_file(dvc, repro_dir):
+def test_recursive_repro_on_stage_file(dvc_repo, repro_dir):
     """
     Test recursive repro on a stage file instead of directory
     """
-    stages = dvc.reproduce(
-        repro_dir["origin_copy_2"].relpath, recursive=True, force=True
+    stages = dvc_repo.reproduce(
+        repro_dir.first_stage, recursive=True, force=True
     )
-    assert stages == [repro_dir["origin_copy"], repro_dir["origin_copy_2"]]
+    assert len(stages) == 2
+    names = [stage.relpath for stage in stages]
+    assert repro_dir.source_stage in names
+    assert repro_dir.first_stage in names
 
 
-def test_dvc_formatting_retained(tmp_dir, dvc, run_copy):
-    tmp_dir.dvc_gen("foo", "foo content")
-    stage = run_copy("foo", "foo_copy", fname="foo_copy.dvc")
-    stage_path = tmp_dir / stage.relpath
+@pytest.fixture
+def foo_copy(repo_dir, dvc_repo):
+    stages = dvc_repo.add(repo_dir.FOO)
+    assert len(stages) == 1
+    foo_stage = stages[0]
+    assert foo_stage is not None
+
+    fname = "foo_copy"
+    stage_fname = fname + ".dvc"
+    dvc_repo.run(
+        fname=stage_fname,
+        outs=[fname],
+        deps=[repo_dir.FOO, repo_dir.CODE],
+        cmd="python {} {} {}".format(repo_dir.CODE, repo_dir.FOO, fname),
+    )
+    return {"fname": fname, "stage_fname": stage_fname}
+
+
+def test_dvc_formatting_retained(dvc_repo, foo_copy):
+    root = pathlib.Path(dvc_repo.root_dir)
+    stage_file = root / foo_copy["stage_fname"]
 
     # Add comments and custom formatting to DVC-file
-    lines = list(map(_format_dvc_line, stage_path.read_text().splitlines()))
+    lines = list(map(_format_dvc_line, stage_file.read_text().splitlines()))
     lines.insert(0, "# Starting comment")
     stage_text = "".join(l + "\n" for l in lines)
-    stage_path.write_text(stage_text)
+    stage_file.write_text(stage_text)
 
     # Rewrite data source and repro
-    (tmp_dir / "foo").write_text("new foo")
-    dvc.reproduce("foo_copy.dvc", force=True)
+    (root / "foo").write_text("new_foo")
+    dvc_repo.reproduce(foo_copy["stage_fname"])
 
-    assert _hide_md5(stage_text) == _hide_md5(stage_path.read_text())
+    # All differences should be only about md5
+    assert _hide_md5(stage_text) == _hide_md5(stage_file.read_text())
 
 
 def _format_dvc_line(line):
@@ -1611,12 +1630,10 @@ class TestReproDownstream(TestDvc):
         assert evaluation[2].relpath == "E.dvc"
 
 
-def test_ssh_dir_out(tmp_dir, dvc):
+def test_ssh_dir_out(dvc_repo):
     if not _should_test_ssh():
         pytest.skip()
 
-    tmp_dir.gen({"foo": "foo content"})
-
     # Set up remote and cache
     remote_url = get_ssh_url()
     assert main(["remote", "add", "upstream", remote_url]) == 0
@@ -1626,7 +1643,7 @@ def test_ssh_dir_out(tmp_dir, dvc):
     assert main(["config", "cache.ssh", "sshcache"]) == 0
 
     # Recreating to reread configs
-    repo = DvcRepo(dvc.root_dir)
+    repo = DvcRepo(dvc_repo.root_dir)
 
     url_info = URLInfo(remote_url)
     mkdir_cmd = "mkdir dir-out;cd dir-out;echo 1 > 1.txt; echo 2 > 2.txt"

pip install -e .[all]
parse_log_pytest
pytest
pytest pytest-timeout pytest-cov pytest-xdist pytest-mock flaky mock xmltodict awscli google-compute-engine Pygments collective.checkdocs flake8 psutil flake8-docstrings pydocstyle jaraco.windows mock-ssh-server moto rangehttpserver
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
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
boto==2.49.0
boto3==1.33.13
botocore==1.33.13
cachetools==5.5.2
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
configparser==5.3.0
coverage==7.2.7
crcmod==1.7
cryptography==44.0.2
decorator==5.1.1
distro==1.9.0
docutils==0.16
-e git+https://github.com/iterative/dvc.git@84ec0d49a339a6148b1e92d10c78aa308e9c9df8#egg=dvc
execnet==2.0.2
flake8==5.0.4
flake8-docstrings==1.7.0
flaky==3.8.1
flit_core @ file:///opt/conda/conda-bld/flit-core_1644941570762/work/source/flit_core
flufl.lock==7.1.1
funcy==2.0
future==1.0.0
gitdb==4.0.12
gitdb2==4.0.2
GitPython==3.1.44
google-api-core==1.34.1
google-api-python-client==2.166.0
google-auth==2.38.0
google-auth-httplib2==0.2.0
google-cloud-core==1.5.0
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
humanize==4.6.0
idna==3.10
importlib-metadata==4.2.0
importlib-resources==5.12.0
inflect==3.0.2
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
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
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
pluggy @ file:///tmp/build/80754af9/pluggy_1648042572264/work
ply==3.11
protobuf==3.20.3
psutil==7.0.0
py @ file:///opt/conda/conda-bld/py_1644396412707/work
pyarrow==0.15.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
PyDrive==1.3.1
pyflakes==2.5.0
Pygments==2.17.2
PyNaCl==1.5.0
pyparsing==3.1.4
pytest==7.1.2
pytest-cov==4.1.0
pytest-mock==3.11.1
pytest-timeout==2.3.1
pytest-xdist==3.5.0
python-dateutil==2.8.0
PyYAML==5.1.2
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
six==1.17.0
smmap==5.0.2
snowballstemmer==2.2.0
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work
tqdm==4.67.1
treelib==1.7.1
types-PyYAML==6.0.12.12
typing_extensions @ file:///croot/typing_extensions_1669924550328/work
uritemplate==4.1.1
urllib3==1.26.20
voluptuous==0.14.1
Werkzeug==2.2.3
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
  - typing_extensions=4.4.0=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
      - 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
      - boto==2.49.0
      - boto3==1.33.13
      - botocore==1.33.13
      - cachetools==5.5.2
      - cffi==1.15.1
      - charset-normalizer==3.4.1
      - collective-checkdocs==0.2
      - colorama==0.4.4
      - configobj==5.0.9
      - configparser==5.3.0
      - coverage==7.2.7
      - crcmod==1.7
      - cryptography==44.0.2
      - decorator==5.1.1
      - distro==1.9.0
      - docutils==0.16
      - dvc==0.80.0+84ec0d
      - execnet==2.0.2
      - flake8==5.0.4
      - flake8-docstrings==1.7.0
      - flaky==3.8.1
      - flufl-lock==7.1.1
      - funcy==2.0
      - future==1.0.0
      - gitdb==4.0.12
      - gitdb2==4.0.2
      - gitpython==3.1.44
      - google-api-core==1.34.1
      - google-api-python-client==2.166.0
      - google-auth==2.38.0
      - google-auth-httplib2==0.2.0
      - google-cloud-core==1.5.0
      - 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
      - humanize==4.6.0
      - idna==3.10
      - importlib-metadata==4.2.0
      - importlib-resources==5.12.0
      - inflect==3.0.2
      - 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
      - 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
      - ply==3.11
      - protobuf==3.20.3
      - psutil==7.0.0
      - pyarrow==0.15.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
      - pydrive==1.3.1
      - pyflakes==2.5.0
      - pygments==2.17.2
      - pynacl==1.5.0
      - pyparsing==3.1.4
      - pytest-cov==4.1.0
      - pytest-mock==3.11.1
      - pytest-timeout==2.3.1
      - pytest-xdist==3.5.0
      - python-dateutil==2.8.0
      - pyyaml==5.1.2
      - 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
      - six==1.17.0
      - smmap==5.0.2
      - snowballstemmer==2.2.0
      - tqdm==4.67.1
      - treelib==1.7.1
      - types-pyyaml==6.0.12.12
      - uritemplate==4.1.1
      - urllib3==1.26.20
      - voluptuous==0.14.1
      - werkzeug==2.2.3
      - xmltodict==0.14.2
      - zc-lockfile==3.0.post1
prefix: /opt/conda/envs/dvc

tests/func/test_get.py::test_get_from_non_dvc_repo tests/func/test_get.py::test_absolute_file_outside_git_repo
tests/func/test_repro.py::TestReproShell::test
tests/func/test_get.py::test_get_repo_file tests/func/test_get.py::test_get_repo_dir tests/func/test_get.py::test_get_git_file tests/func/test_get.py::test_get_git_dir tests/func/test_get.py::test_cache_type_is_properly_overridden tests/func/test_get.py::test_get_repo_rev tests/func/test_get.py::test_get_a_dvc_file tests/func/test_get.py::test_get_full_dvc_path tests/func/test_get.py::test_non_cached_output tests/func/test_get.py::test_absolute_file_outside_repo tests/func/test_get.py::test_unknown_path tests/func/test_get.py::test_get_to_dir[.] tests/func/test_get.py::test_get_to_dir[dir] tests/func/test_get.py::test_get_to_dir[dir/subdir] tests/func/test_get.py::test_get_from_non_dvc_master tests/func/test_repro.py::TestReproFail::test tests/func/test_repro.py::TestReproCyclicGraph::test tests/func/test_repro.py::TestReproWorkingDirectoryAsOutput::test tests/func/test_repro.py::TestReproWorkingDirectoryAsOutput::test_nested tests/func/test_repro.py::TestReproWorkingDirectoryAsOutput::test_similar_paths tests/func/test_repro.py::TestReproDepUnderDir::test tests/func/test_repro.py::TestReproDepDirWithOutputsUnderIt::test tests/func/test_repro.py::TestReproNoDeps::test tests/func/test_repro.py::TestReproForce::test tests/func/test_repro.py::TestReproChangedCode::test tests/func/test_repro.py::TestReproChangedData::test tests/func/test_repro.py::TestReproDry::test tests/func/test_repro.py::TestReproUpToDate::test tests/func/test_repro.py::TestReproDryNoExec::test tests/func/test_repro.py::TestReproChangedDeepData::test tests/func/test_repro.py::TestReproIgnoreBuildCache::test tests/func/test_repro.py::TestReproPipeline::test tests/func/test_repro.py::TestReproPipeline::test_cli tests/func/test_repro.py::TestReproPipelines::test tests/func/test_repro.py::TestReproPipelines::test_cli tests/func/test_repro.py::TestReproLocked::test tests/func/test_repro.py::TestReproLocked::test_non_existing tests/func/test_repro.py::TestReproLockedCallback::test tests/func/test_repro.py::TestReproLockedUnchanged::test tests/func/test_repro.py::TestReproMetricsAddUnchanged::test tests/func/test_repro.py::TestReproPhony::test tests/func/test_repro.py::TestNonExistingOutput::test tests/func/test_repro.py::TestReproDataSource::test tests/func/test_repro.py::TestReproChangedDir::test tests/func/test_repro.py::TestReproChangedDirData::test tests/func/test_repro.py::TestReproMissingMd5InStageFile::test tests/func/test_repro.py::TestCmdRepro::test tests/func/test_repro.py::TestCmdReproChdirCwdBackwardCompatible::test tests/func/test_repro.py::TestCmdReproChdir::test tests/func/test_repro.py::TestReproExternalBase::test tests/func/test_repro.py::TestReproExternalS3::test tests/func/test_repro.py::TestReproExternalGS::test tests/func/test_repro.py::TestReproExternalHDFS::test tests/func/test_repro.py::TestReproExternalSSH::test tests/func/test_repro.py::TestReproExternalLOCAL::test tests/func/test_repro.py::TestReproExternalHTTP::test tests/func/test_repro.py::TestReproAllPipelines::test tests/func/test_repro.py::TestReproNoCommit::test tests/func/test_repro.py::TestReproAlreadyCached::test tests/func/test_repro.py::TestReproAlreadyCached::test_force_import tests/func/test_repro.py::TestReproAlreadyCached::test_force_with_dependencies tests/func/test_repro.py::TestShouldDisplayMetricsOnReproWithMetricsOption::test tests/func/test_repro.py::test_recursive_repro_default tests/func/test_repro.py::test_recursive_repro_single tests/func/test_repro.py::test_recursive_repro_single_force tests/func/test_repro.py::test_recursive_repro_empty_dir tests/func/test_repro.py::test_recursive_repro_recursive_missing_file tests/func/test_repro.py::test_recursive_repro_on_stage_file tests/func/test_repro.py::test_dvc_formatting_retained tests/func/test_repro.py::TestReproDownstream::test
dvc/repo/get.py dvc/exceptions.py dvc/command/get.py dvc/command/imp.py dvc/scm/git/__init__.py
dvc/repo/get.py dvc/exceptions.py dvc/command/get.py dvc/command/imp.py dvc/scm/git/__init__.py