diff --git a/dvc/api.py b/dvc/api.py index a2235653a6..506baa6c82 100644 --- a/dvc/api.py +++ b/dvc/api.py @@ -7,7 +7,6 @@ except ImportError: from contextlib import GeneratorContextManager as GCM -from dvc.utils import remove from dvc.utils.compat import urlparse from dvc.repo import Repo from dvc.external_repo import ExternalRepo @@ -70,10 +69,9 @@ def _make_repo(repo_url, rev=None): yield Repo(repo_url) else: tmp_dir = tempfile.mkdtemp("dvc-repo") + ext_repo = ExternalRepo(tmp_dir, url=repo_url, rev=rev) try: - ext_repo = ExternalRepo(tmp_dir, url=repo_url, rev=rev) ext_repo.install() yield ext_repo.repo finally: - ext_repo.repo.scm.git.close() - remove(tmp_dir) + ext_repo.uninstall() diff --git a/dvc/external_repo.py b/dvc/external_repo.py index cbffeee872..2bc2668f9d 100644 --- a/dvc/external_repo.py +++ b/dvc/external_repo.py @@ -5,7 +5,7 @@ import logging import shortuuid -from funcy import cached_property +from funcy import cached_property, retry from schema import Optional from dvc.config import Config @@ -138,7 +138,16 @@ def uninstall(self): ) return - remove(self.path) + # If repo has been initialized then we need to close its git repo + if "repo" in self.__dict__: + self.repo.scm.git.close() + + if os.name == "nt": + # git.exe may hang for a while not permitting to remove temp dir + os_retry = retry(5, errors=OSError, timeout=0.1) + os_retry(remove)(self.path) + else: + remove(self.path) def update(self): self.repo.scm.fetch(self.rev) diff --git a/dvc/repo/get.py b/dvc/repo/get.py index f234c61a7c..0871b40232 100644 --- a/dvc/repo/get.py +++ b/dvc/repo/get.py @@ -5,7 +5,6 @@ from dvc.path_info import PathInfo from dvc.external_repo import ExternalRepo from dvc.utils.compat import urlparse -from dvc.utils import remove @staticmethod @@ -19,8 +18,8 @@ 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())) + erepo = ExternalRepo(tmp_dir, url=url, rev=rev) try: - erepo = ExternalRepo(tmp_dir, url=url, rev=rev) erepo.install() # Try any links possible to avoid data duplication. # @@ -42,7 +41,5 @@ def get(url, path, out=None, rev=None): o.path_info = PathInfo(os.path.abspath(out)) with o.repo.state: o.checkout() - erepo.repo.scm.git.close() finally: - if os.path.exists(tmp_dir): - remove(tmp_dir) + erepo.uninstall()