diff --git a/dvc/command/repro.py b/dvc/command/repro.py index 59727c3d8..05b82e879 100644 --- a/dvc/command/repro.py +++ b/dvc/command/repro.py @@ -33,6 +33,7 @@ class CmdRepro(CmdBase): pipeline=self.args.pipeline, all_pipelines=self.args.all_pipelines, ignore_build_cache=self.args.ignore_build_cache, + no_commit=self.args.no_commit, ) if len(stages) == 0: @@ -124,4 +125,10 @@ def add_parser(subparsers, parent_parser): help="Reproduce all descendants of a changed stage even if their " "direct dependencies didn't change.", ) + repro_parser.add_argument( + "--no-commit", + action="store_true", + default=False, + help="Don't put files/directories into cache.", + ) repro_parser.set_defaults(func=CmdRepro) diff --git a/dvc/repo/reproduce.py b/dvc/repo/reproduce.py index a367f396f..0bc6d8656 100644 --- a/dvc/repo/reproduce.py +++ b/dvc/repo/reproduce.py @@ -6,7 +6,7 @@ import dvc.logger as logger from dvc.exceptions import ReproductionError -def _reproduce_stage(stages, node, force, dry, interactive): +def _reproduce_stage(stages, node, force, dry, interactive, no_commit): stage = stages[node] if stage.locked: @@ -15,7 +15,9 @@ def _reproduce_stage(stages, node, force, dry, interactive): " not going to be reproduced.".format(path=stage.relpath) ) - stage = stage.reproduce(force=force, dry=dry, interactive=interactive) + stage = stage.reproduce( + force=force, dry=dry, interactive=interactive, no_commit=no_commit + ) if not stage: return [] @@ -35,6 +37,7 @@ def reproduce( pipeline=False, all_pipelines=False, ignore_build_cache=False, + no_commit=False, ): from dvc.stage import Stage @@ -75,6 +78,7 @@ def reproduce( dry=dry, interactive=interactive, ignore_build_cache=ignore_build_cache, + no_commit=no_commit, ) ret.extend(stages) @@ -91,6 +95,7 @@ def _reproduce( dry=False, interactive=False, ignore_build_cache=False, + no_commit=False, ): import networkx as nx from dvc.stage import Stage @@ -102,23 +107,34 @@ def _reproduce( if recursive: ret = _reproduce_stages( - G, stages, node, force, dry, interactive, ignore_build_cache + G, + stages, + node, + force, + dry, + interactive, + ignore_build_cache, + no_commit, ) else: - ret = _reproduce_stage(stages, node, force, dry, interactive) + ret = _reproduce_stage( + stages, node, force, dry, interactive, no_commit + ) return ret def _reproduce_stages( - G, stages, node, force, dry, interactive, ignore_build_cache + G, stages, node, force, dry, interactive, ignore_build_cache, no_commit ): import networkx as nx result = [] for n in nx.dfs_postorder_nodes(G, node): try: - ret = _reproduce_stage(stages, n, force, dry, interactive) + ret = _reproduce_stage( + stages, n, force, dry, interactive, no_commit + ) if len(ret) != 0 and ignore_build_cache: # NOTE: we are walking our pipeline from the top to the diff --git a/dvc/stage.py b/dvc/stage.py index 3f9a77b90..6d12e55c5 100644 --- a/dvc/stage.py +++ b/dvc/stage.py @@ -251,7 +251,9 @@ class Stage(object): self.remove_outs(ignore_remove=True) os.unlink(self.path) - def reproduce(self, force=False, dry=False, interactive=False): + def reproduce( + self, force=False, dry=False, interactive=False, no_commit=False + ): if not self.changed() and not force: return None @@ -268,7 +270,7 @@ class Stage(object): logger.info("Reproducing '{stage}'".format(stage=self.relpath)) - self.run(dry=dry) + self.run(dry=dry, no_commit=no_commit) logger.debug("'{stage}' was reproduced".format(stage=self.relpath)) diff --git a/tests/test_repro.py b/tests/test_repro.py index 1748d90d7..d38b26c51 100644 --- a/tests/test_repro.py +++ b/tests/test_repro.py @@ -1269,3 +1269,11 @@ class TestReproAllPipelines(TestDvc): ret = main(["repro", "--all-pipelines"]) self.assertEqual(ret, 0) self.assertEqual(mock_reproduce.call_count, 4) + + +class TestReproNoCommit(TestRepro): + def test(self): + shutil.rmtree(self.dvc.cache.local.cache_dir) + ret = main(["repro", self.file1_stage, "--no-commit"]) + self.assertEqual(ret, 0) + self.assertEqual(len(os.listdir(self.dvc.cache.local.cache_dir)), 0)