diff --git a/dvc/repo/metrics/show.py b/dvc/repo/metrics/show.py index c03379a5f0..daf4d41b6c 100644 --- a/dvc/repo/metrics/show.py +++ b/dvc/repo/metrics/show.py @@ -1,6 +1,7 @@ import logging from typing import List +from dvc.dvcfile import LockfileCorruptedError from dvc.exceptions import ( MetricDoesNotExistError, NoMetricsFoundError, @@ -35,14 +36,22 @@ def _to_path_infos(metrics: List[BaseOutput]) -> List[PathInfo]: def _collect_metrics(repo, targets, revision, recursive): - metrics, path_infos = collect( - repo, - targets=targets, - output_filter=_is_metric, - recursive=recursive, - rev=revision, - ) - return _to_path_infos(metrics) + list(path_infos) + try: + metrics, path_infos = collect( + repo, + targets=targets, + output_filter=_is_metric, + recursive=recursive, + rev=revision, + ) + + return _to_path_infos(metrics) + list(path_infos) + + except LockfileCorruptedError: + logger.warning( + "Corrupt lockfile at revision %s. Ignoring in metrics.", revision + ) + return [] def _extract_metrics(metrics, path, rev): diff --git a/tests/func/metrics/test_show.py b/tests/func/metrics/test_show.py index c9cd85c39c..48375a984b 100644 --- a/tests/func/metrics/test_show.py +++ b/tests/func/metrics/test_show.py @@ -1,4 +1,5 @@ import os +import shutil import pytest @@ -226,3 +227,26 @@ def test_metrics_show_overlap( with pytest.raises(OverlappingOutputPathsError): dvc.metrics.show() + + +def test_skips_broken_commits(tmp_dir, scm, dvc): + dvc.run( + cmd="echo foo: 1.1 > metrics.yaml", + metrics=["metrics.yaml"], + name="test", + ) + scm.add(["dvc.yaml", ".gitignore", "dvc.lock"]) + scm.commit("initial") + + shutil.copyfile("dvc.lock", "dvc.lock.bak") + tmp_dir.gen("dvc.lock", "<<<<< broken commit") + scm.add(["dvc.lock"]) + scm.commit("accidental broken commit") + + shutil.copyfile("dvc.lock.bak", "dvc.lock") + scm.add(["dvc.lock"]) + scm.commit("revert breakage") + + assert list(dvc.metrics.show(all_commits=True).values())[0] == { + "metrics.yaml": {"foo": 1.1} + }