From 990e834f1d885d6aaea23645f5eaf9aeef433509 Mon Sep 17 00:00:00 2001 From: Ruslan Kuprieiev Date: Thu, 16 Mar 2023 01:31:14 +0200 Subject: [PATCH] repo: open: handle bare git repos If we are asked to open a potentially unitialized repo, we need to make sure it is not a bare git repo, so that we don't accidentally start putting dvc files inside git control dir. Discovered while working on #8789 --- dvc/repo/__init__.py | 2 ++ tests/func/test_repo.py | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/dvc/repo/__init__.py b/dvc/repo/__init__.py index 12b3b5a91..27945559a 100644 --- a/dvc/repo/__init__.py +++ b/dvc/repo/__init__.py @@ -125,6 +125,8 @@ class Repo: if not scm: try: scm = SCM(root_dir or os.curdir) + if scm.dulwich.repo.bare: + raise NotDvcRepoError(f"{scm.root_dir} is a bare git repo") except SCMError: scm = SCM(os.curdir, no_scm=True) diff --git a/tests/func/test_repo.py b/tests/func/test_repo.py index 8fcc7a104..6b2ae808b 100644 --- a/tests/func/test_repo.py +++ b/tests/func/test_repo.py @@ -1,6 +1,32 @@ +import os + from dvc.cachemgr import CacheManager from dvc.dvcfile import LOCK_FILE, PROJECT_FILE from dvc.fs import system +from dvc.repo import Repo +from dvc.scm import Git + + +def test_open_bare(tmp_dir, scm, dvc, tmp_path_factory): + tmp_dir.dvc_gen( + { + "dir123": {"foo": "foo content"}, + "dirextra": {"extrafoo": "extra foo content"}, + }, + commit="initial", + ) + + url = os.fspath(tmp_path_factory.mktemp("bare")) + Git.init(url, bare=True).close() + + scm.gitpython.repo.create_remote("origin", url) + scm.gitpython.repo.remote("origin").push("master") + + with Repo.open(url) as repo: + assert repo.scm.root_dir != url + + with Repo.open(url, uninitialized=True) as repo: + assert repo.scm.root_dir != url def test_destroy(tmp_dir, dvc, run_copy):