Repository: iterative/dvc
Pull request: exp: make run/save less noisy
Closes #9239 

Not sure if we need additional tests for this



Problem statement:
exp run: less verbose output
The current output of `dvc exp run` seems unnecessarily verbose:

```bash
$ dvc exp run -S prepare.split=0.25
Couldn't find a valid Studio Repo URL.
You can try manually setting the environment variable `STUDIO_REPO_URL`.
'data/data.xml.dvc' didn't change, skipping
Running stage 'prepare':
> python src/prepare.py data/data.xml
Updating lock file 'dvc.lock'

Running stage 'featurize':
> python src/featurization.py data/prepared data/features
The input data frame data/prepared/train.tsv size is (30062, 3)
The output matrix data/features/train.pkl size is (30062, 502) and data type is float64
The input data frame data/prepared/test.tsv size is (9938, 3)
The output matrix data/features/test.pkl size is (9938, 502) and data type is float64
Updating lock file 'dvc.lock'

Running stage 'train':
> python src/train.py data/features model.pkl
Input matrix size (30062, 502)
X matrix size (30062, 500)
Y matrix size (30062,)
Updating lock file 'dvc.lock'

Running stage 'evaluate':
> python src/evaluate.py model.pkl data/features
Updating lock file 'dvc.lock'

To track the changes with git, run:

        git add dvc.lock src/train.py eval/prc src/evaluate.py src/featurization.py dvc.yaml params.yaml eval/live/plots src/prepare.py eval/live/metrics.json

To enable auto staging, run:

        dvc config core.autostage true

Ran experiment(s): barer-acts
Experiment results have been applied to your workspace.

To promote an experiment to a Git branch run:

        dvc exp branch <exp> <branch>
```

This part from `dvc repro` doesn't even make much sense for `dvc exp run`:

```
To track the changes with git, run:

        git add dvc.lock src/train.py eval/prc src/evaluate.py src/featurization.py dvc.yaml params.yaml eval/live/plots src/prepare.py eval/live/metrics.json

To enable auto staging, run:

        dvc config core.autostage true
```

The `exp branch` hint also seems unnecessary:

```

To promote an experiment to a Git branch run:

        dvc exp branch <exp> <branch>
```

Hints from issue discussion:

Commit message: exp: make run/save less noisy

Patch to review:
diff --git a/dvc/commands/experiments/save.py b/dvc/commands/experiments/save.py
index 227aa0f90a..d81f1579b5 100644
--- a/dvc/commands/experiments/save.py
+++ b/dvc/commands/experiments/save.py
@@ -27,10 +27,6 @@ def run(self):
         else:
             name = self.repo.experiments.get_exact_name([ref])[ref]
             ui.write(f"Experiment has been saved as: {name}")
-            ui.write(
-                "\nTo promote an experiment to a Git branch run:\n\n"
-                "\tdvc exp branch <exp> <branch>\n"
-            )
 
         return 0
 
diff --git a/dvc/repo/experiments/__init__.py b/dvc/repo/experiments/__init__.py
index c77f04e08a..e351c15c34 100644
--- a/dvc/repo/experiments/__init__.py
+++ b/dvc/repo/experiments/__init__.py
@@ -210,10 +210,6 @@ def _log_reproduced(self, revs: Iterable[str], tmp_dir: bool = False):
             )
         else:
             ui.write("Experiment results have been applied to your workspace.")
-        ui.write(
-            "\nTo promote an experiment to a Git branch run:\n\n"
-            "\tdvc exp branch <exp> <branch>\n"
-        )
 
     def new(
         self,
diff --git a/dvc/repo/experiments/executor/base.py b/dvc/repo/experiments/executor/base.py
index a9f95c5c47..51da4fdb92 100644
--- a/dvc/repo/experiments/executor/base.py
+++ b/dvc/repo/experiments/executor/base.py
@@ -129,7 +129,6 @@ class BaseExecutor(ABC):
 
     PACKED_ARGS_FILE = "repro.dat"
     WARN_UNTRACKED = False
-    QUIET = False
     INFOFILE_EXT = ".run"
     DEFAULT_LOCATION: str = "workspace"
 
@@ -602,8 +601,7 @@ def _repro_dvc(  # noqa: C901
             info.status = TaskStatus.RUNNING
             if infofile is not None:
                 info.dump_json(infofile)
-            if cls.QUIET:
-                dvc.scm_context.quiet = cls.QUIET
+            dvc.scm_context.quiet = True
             old_cwd = os.getcwd()
 
             for path in copy_paths or []:
diff --git a/tests/unit/command/test_experiments.py b/tests/unit/command/test_experiments.py
index 582b9b45e2..76c23daa1a 100644
--- a/tests/unit/command/test_experiments.py
+++ b/tests/unit/command/test_experiments.py
@@ -418,7 +418,7 @@ def test_experiments_remove_invalid(dvc, scm, mocker, capsys, caplog):
     )
 
 
-def test_experiments_save(dvc, scm, mocker):
+def test_experiments_save(dvc, scm, mocker, caplog):
     cli_args = parse_args(["exp", "save", "--name", "exp-name", "--force"])
     assert cli_args.func == CmdExperimentsSave
 
diff --git a/tests/unit/repo/test_scm_context.py b/tests/unit/repo/test_scm_context.py
index 52e3b10d60..21978c0a15 100644
--- a/tests/unit/repo/test_scm_context.py
+++ b/tests/unit/repo/test_scm_context.py
@@ -100,13 +100,14 @@ def test_scm_context_on_no_files_to_track(caplog, scm_context, autostage, quiet)
     assert not caplog.text
 
 
-def test_scm_context_remind_to_track(caplog, scm_context):
-    with scm_context() as context:
+@pytest.mark.parametrize("quiet", [True, False])
+def test_scm_context_remind_to_track(caplog, scm_context, quiet):
+    with scm_context(quiet=quiet) as context:
         context.track_file("foo")
         context.track_file("lorem ipsum")
         assert context.files_to_track == {"foo", "lorem ipsum"}
 
-    if isinstance(scm_context.scm, NoSCM):
+    if quiet or isinstance(scm_context.scm, NoSCM):
         assert not caplog.text
     else:
         assert "To track the changes with git, run:" in caplog.text


Code review comments:
diff_hunk: @@ -418,7 +418,7 @@ def test_experiments_remove_invalid(dvc, scm, mocker, capsys, caplog):
     )
 
 
-def test_experiments_save(dvc, scm, mocker):
+def test_experiments_save(dvc, scm, mocker, caplog):
path: tests/unit/command/test_experiments.py
text: @user1:
```suggestion
def test_experiments_save(dvc, scm, mocker):
```

I suppose it made it here by accident?