Skip to content

Commit d487108

Browse files
committed
repo: try to support opening uninitialized/broken repositories
This `_get_remote_config()` should use `uninitialized=True` so that it supports more broader kinds of broken/partially-initialized repositories, including some that have `.dvc` directory missing, or `.git` directory missing. This partially reverts #10719. #10608 is also fixed, and no longer requires `core.no_scm` to be passed. This was already supported by `dvc.api.get_url` as it uses `uninitialized=True`, but this was not respected in `_get_remote_config()` where it would fail before. That said, this whole `open_repo`/`_get_remote_config` is terribly broken. For one, it is opening a local repository, and forcing it's remote config to a repository opened with `Repo(rev=...)`, where the config may be different.
1 parent f3be7d7 commit d487108

File tree

2 files changed

+15
-26
lines changed

2 files changed

+15
-26
lines changed

dvc/repo/open_repo.py

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import copy
21
import os
32
import tempfile
43
import threading
@@ -51,7 +50,7 @@ def open_repo(url, *args, **kwargs):
5150
if os.path.exists(url):
5251
url = os.path.abspath(url)
5352
try:
54-
config = _get_remote_config(url, *args, **kwargs)
53+
config = _get_remote_config(url)
5554
config.update(kwargs.get("config") or {})
5655
kwargs["config"] = config
5756
return Repo(url, *args, **kwargs)
@@ -98,24 +97,9 @@ def clean_repos():
9897
_remove(path)
9998

10099

101-
def _get_remote_config(url, *args, **kwargs):
100+
def _get_remote_config(url):
102101
try:
103-
# Deepcopy to prevent modifying the original `kwargs['config']`
104-
config = copy.deepcopy(kwargs.get("config"))
105-
106-
# Import operations will use this function to get the remote's cache. However,
107-
# while the `url` sent will point to the external repo, the cache information
108-
# in `kwargs["config"]["cache"]["dir"]`) will point to the local repo,
109-
# see `dvc/dependency/repo.py:RepoDependency._make_fs()`
110-
#
111-
# This breaks this function, since we'd be instructing `Repo()` to use the wrong
112-
# cache to being with. We need to remove the cache info from `kwargs["config"]`
113-
# to read the actual remote repo data.
114-
if config:
115-
config.pop("cache", None)
116-
117-
repo = Repo(url, config=config)
118-
102+
repo = Repo(url, uninitialized=True)
119103
except NotDvcRepoError:
120104
return {}
121105

@@ -125,10 +109,16 @@ def _get_remote_config(url, *args, **kwargs):
125109
# Fill the empty upstream entry with a new remote pointing to the
126110
# original repo's cache location.
127111
name = "auto-generated-upstream"
128-
return {
129-
"core": {"remote": name},
130-
"remote": {name: {"url": repo.cache.local_cache_dir}},
131-
}
112+
try:
113+
local_cache_dir = repo.cache.local_cache_dir
114+
except AttributeError:
115+
# if the `.dvc` dir is missing, we get an AttributeError
116+
return {}
117+
else:
118+
return {
119+
"core": {"remote": name},
120+
"remote": {name: {"url": local_cache_dir}},
121+
}
132122

133123
# Use original remote to make sure that we are using correct url,
134124
# credential paths, etc if they are relative to the config location.

tests/func/api/test_data.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from dvc import api
77
from dvc.exceptions import OutputNotFoundError, PathMissingError
8-
from dvc.scm import CloneError, SCMError
8+
from dvc.scm import CloneError
99
from dvc.testing.api_tests import TestAPI # noqa: F401
1010
from dvc.testing.tmp_dir import make_subrepo
1111
from dvc.utils.fs import remove
@@ -80,8 +80,7 @@ def test_get_url_ignore_scm(tmp_dir, dvc, cloud, scm):
8080
(tmp_dir / ".git").rename(tmp_dir / "gitless_environment")
8181

8282
# Test failure mode when trying to access with git
83-
with pytest.raises(SCMError, match="is not a git repository"):
84-
api.get_url("foo", repo=repo_posix)
83+
assert api.get_url("foo", repo=repo_posix) == expected_url
8584

8685
# Test successful access by ignoring git
8786
assert (

0 commit comments

Comments
 (0)