Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 30 additions & 16 deletions dvc/external_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def __init__(self, root_dir, url):
super().__init__(root_dir)
self.url = url
self._set_cache_dir()
self._set_upstream()
self._fix_upstream()

def pull_to(self, path, to_info):
"""
Expand Down Expand Up @@ -123,21 +123,35 @@ def _set_cache_dir(self):

self.cache.local.cache_dir = cache_dir

def _set_upstream(self):
# check if the URL is local and no default remote is present
# add default remote pointing to the original repo's cache location
if os.path.isdir(self.url):
if not self.config["core"].get("remote"):
src_repo = Repo(self.url)
try:
cache_dir = src_repo.cache.local.cache_dir
finally:
src_repo.close()

self.config["remote"]["auto-generated-upstream"] = {
"url": cache_dir
}
self.config["core"]["remote"] = "auto-generated-upstream"
def _fix_upstream(self):
Comment thread
tizoc marked this conversation as resolved.
if not os.path.isdir(self.url):
return

remote_name = self.config["core"].get("remote")
src_repo = Repo(self.url)
try:
if remote_name:
self._fix_local_remote(src_repo, remote_name)
else:
self._add_upstream(src_repo)
finally:
src_repo.close()

def _fix_local_remote(self, src_repo, remote_name):
# If a remote URL is relative to the source repo,
# it will have changed upon config load and made
# relative to this new repo. Restore the old one here.
new_remote = self.config["remote"][remote_name]
old_remote = src_repo.config["remote"][remote_name]
if new_remote["url"] != old_remote["url"]:
new_remote["url"] = old_remote["url"]

Comment on lines +146 to +148
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would at least add a comment about what is going on here, though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Btw, should I squash all commits into a single one?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you wish. But we'll squash automatically anyways πŸ™‚ Though if you think this is a final patch, you need to remove WIP prefix from the header.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah cool! no need then. "WIP" removed.

def _add_upstream(self, src_repo):
# Fill the empty upstream entry with a new remote pointing to the
# original repo's cache location.
cache_dir = src_repo.cache.local.cache_dir
self.config["remote"]["auto-generated-upstream"] = {"url": cache_dir}
self.config["core"]["remote"] = "auto-generated-upstream"


class ExternalGitRepo:
Expand Down
31 changes: 31 additions & 0 deletions tests/func/test_external_repo.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import os
import shutil

from mock import patch
from dvc.compat import fspath

from dvc.external_repo import external_repo
from dvc.scm.git import Git
from dvc.remote import RemoteLOCAL
from dvc.utils import relpath


def test_external_repo(erepo_dir):
Expand Down Expand Up @@ -88,3 +90,32 @@ def test_pull_subdir_file(tmp_dir, erepo_dir):

assert dest.is_file()
assert dest.read_text() == "contents"


def test_relative_remote(erepo_dir, tmp_dir):
# these steps reproduce the script on this issue:
# https://github.com/iterative/dvc/issues/2756
with erepo_dir.chdir():
erepo_dir.dvc_gen("file", "contents", commit="create file")

upstream_dir = tmp_dir
upstream_url = relpath(upstream_dir, erepo_dir)
with erepo_dir.dvc.config.edit() as conf:
conf["remote"]["upstream"] = {"url": upstream_url}
conf["core"]["remote"] = "upstream"
Comment thread
tizoc marked this conversation as resolved.

erepo_dir.scm_add(
erepo_dir.dvc.config.files["repo"], commit="Update dvc config"
)
erepo_dir.dvc.push()

(erepo_dir / "file").unlink()
shutil.rmtree(erepo_dir.dvc.cache.local.cache_dir)

url = fspath(erepo_dir)

with external_repo(url) as repo:
assert os.path.isabs(repo.config["remote"]["upstream"]["url"])
assert os.path.isdir(repo.config["remote"]["upstream"]["url"])
with repo.open_by_relpath("file") as fd:
assert fd.read() == "contents"