diff --git a/dvc/repo/diff.py b/dvc/repo/diff.py index bdc886c542..5a06875144 100644 --- a/dvc/repo/diff.py +++ b/dvc/repo/diff.py @@ -52,6 +52,9 @@ def _exists(output): if _exists(output) } + if self.scm.no_commits: + return {} + working_tree = self.tree a_tree = self.scm.get_tree(a_rev) b_tree = self.scm.get_tree(b_rev) if b_rev else working_tree diff --git a/dvc/repo/metrics/diff.py b/dvc/repo/metrics/diff.py index b65e5e03a3..c6c68c67d3 100644 --- a/dvc/repo/metrics/diff.py +++ b/dvc/repo/metrics/diff.py @@ -14,6 +14,9 @@ def _get_metrics(repo, *args, rev=None, **kwargs): def diff(repo, *args, a_rev=None, b_rev=None, **kwargs): + if repo.scm.no_commits: + return {} + with_unchanged = kwargs.pop("all", False) old = _get_metrics(repo, *args, **kwargs, rev=(a_rev or "HEAD")) diff --git a/dvc/repo/params/diff.py b/dvc/repo/params/diff.py index cb7e05654d..35b5881304 100644 --- a/dvc/repo/params/diff.py +++ b/dvc/repo/params/diff.py @@ -13,6 +13,9 @@ def _get_params(repo, *args, rev=None, **kwargs): def diff(repo, *args, a_rev=None, b_rev=None, **kwargs): + if repo.scm.no_commits: + return {} + with_unchanged = kwargs.pop("all", False) old = _get_params(repo, *args, **kwargs, rev=(a_rev or "HEAD")) diff --git a/dvc/scm/git/__init__.py b/dvc/scm/git/__init__.py index 6d400725f1..7429ae47c0 100644 --- a/dvc/scm/git/__init__.py +++ b/dvc/scm/git/__init__.py @@ -439,3 +439,7 @@ def _verify_dvc_hooks(self): self._verify_hook("post-checkout") self._verify_hook("pre-commit") self._verify_hook("pre-push") + + @property + def no_commits(self): + return not self.list_all_commits() diff --git a/tests/dir_helpers.py b/tests/dir_helpers.py index 3ad9a8bf56..cd30ab44ef 100644 --- a/tests/dir_helpers.py +++ b/tests/dir_helpers.py @@ -63,6 +63,7 @@ "erepo_dir", "git_dir", "setup_remote", + "git_init", ] @@ -96,7 +97,7 @@ def init(self, *, scm=False, dvc=False): str_path = fspath(self) if scm: - _git_init(str_path) + git_init(str_path) if dvc: self.dvc = Repo.init( str_path, no_scm=not scm and not hasattr(self, "scm") @@ -243,7 +244,7 @@ def dvc(tmp_dir): return tmp_dir.dvc -def _git_init(path): +def git_init(path): from git import Repo from git.exc import GitCommandNotFound diff --git a/tests/func/metrics/test_diff.py b/tests/func/metrics/test_diff.py index 8aba505a26..0b04e9bef7 100644 --- a/tests/func/metrics/test_diff.py +++ b/tests/func/metrics/test_diff.py @@ -134,3 +134,14 @@ def test_metrics_diff_with_unchanged(tmp_dir, scm, dvc): "xyz": {"old": 10, "new": 10, "diff": 0}, } } + + +def test_no_commits(tmp_dir): + from dvc.repo import Repo + from dvc.scm.git import Git + from tests.dir_helpers import git_init + + git_init(".") + assert Git().no_commits + + assert Repo.init().metrics.diff() == {} diff --git a/tests/func/params/test_diff.py b/tests/func/params/test_diff.py index d34bbaf897..d4bc3a2bbd 100644 --- a/tests/func/params/test_diff.py +++ b/tests/func/params/test_diff.py @@ -119,3 +119,14 @@ def test_pipeline_tracked_params(tmp_dir, scm, dvc, run_copy): assert dvc.params.diff(a_rev="HEAD~2") == { "params.yaml": {"foo": {"old": "bar", "new": "qux"}} } + + +def test_no_commits(tmp_dir): + from dvc.repo import Repo + from dvc.scm.git import Git + from tests.dir_helpers import git_init + + git_init(".") + assert Git().no_commits + + assert Repo.init().params.diff() == {} diff --git a/tests/func/test_diff.py b/tests/func/test_diff.py index 66579c2fd1..615d0eafa7 100644 --- a/tests/func/test_diff.py +++ b/tests/func/test_diff.py @@ -214,3 +214,14 @@ def test_diff_dirty(tmp_dir, scm, dvc): def test_no_changes(tmp_dir, scm, dvc): tmp_dir.dvc_gen("file", "first", commit="add a file") assert dvc.diff() == {} + + +def test_no_commits(tmp_dir): + from dvc.repo import Repo + from dvc.scm.git import Git + from tests.dir_helpers import git_init + + git_init(".") + assert Git().no_commits + + assert Repo.init().diff() == {} diff --git a/tests/unit/scm/test_git.py b/tests/unit/scm/test_git.py index 90337e0f9f..23087fbf43 100644 --- a/tests/unit/scm/test_git.py +++ b/tests/unit/scm/test_git.py @@ -70,3 +70,17 @@ def test_is_tracked_unicode(tmp_dir, scm): tmp_dir.gen("ṳṋṭṝḁḉḵḗḋ", "untracked") assert scm.is_tracked("ṭṝḁḉḵḗḋ") assert not scm.is_tracked("ṳṋṭṝḁḉḵḗḋ") + + +def test_no_commits(tmp_dir): + from tests.dir_helpers import git_init + from dvc.scm.git import Git + + git_init(".") + assert Git().no_commits + + tmp_dir.gen("foo", "foo") + Git().add(["foo"]) + Git().commit("foo") + + assert not Git().no_commits