Skip to content
Open
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
7 changes: 7 additions & 0 deletions dvc/stage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,13 @@ def reproduce(self, interactive=False, **kwargs) -> Optional["Stage"]:
allow_missing = kwargs.get("allow_missing", False)
pull = kwargs.get("pull", False)
upstream = kwargs.pop("upstream", None)
if self.frozen and not self.is_import:
# `dvc freeze` documents a frozen stage as always treated as
# unchanged, so `--force` must not reproduce it. The command is
# skipped in `run()` either way, but reproducing re-saves the stage
# and rewrites its dependency hashes in dvc.lock. Falling through to
# the checks below still lets it restore missing outputs.
force = False
if force:
pass
# Skip stages with missing data if otherwise unchanged
Expand Down
17 changes: 16 additions & 1 deletion tests/func/repro/test_repro.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from dvc.stage.exceptions import StageFileDoesNotExistError, StageNotFound
from dvc.testing import matchers as M
from dvc.utils.fs import remove
from dvc.utils.serialize import modify_yaml
from dvc.utils.serialize import load_yaml, modify_yaml
from dvc_data.hashfile.hash import file_md5


Expand Down Expand Up @@ -56,6 +56,21 @@ def test_repro_frozen(tmp_dir, dvc, run_copy):
assert stages == [data_stage, stage0]


def test_repro_frozen_force(tmp_dir, dvc, run_copy):
"""Check that `--force` doesn't rewrite a frozen stage's dependency hashes"""
tmp_dir.dvc_gen("data", "foo")
run_copy("data", "stage0", name="copy-data-stage0")
run_copy("stage0", "stage1", name="copy-data-stage1")

dvc.freeze("copy-data-stage1")
frozen_before = load_yaml("dvc.lock")["stages"]["copy-data-stage1"]

tmp_dir.gen("stage0", "bar")

assert dvc.reproduce("copy-data-stage1", force=True) == []
assert load_yaml("dvc.lock")["stages"]["copy-data-stage1"] == frozen_before


def test_downstream(tmp_dir, dvc):
# The dependency graph should look like this:
#
Expand Down
Loading