Repository: iterative/dvc

Issue:
cannot remove dvc.lock autostaging
# Bug Report

## DVC autostages by default, and I cannot disable it.


## Description

DVC forces autostage, even if I run:
```dvc config core.autostage false```

My .dvc/config file:
```
[core]
    remote = storage
    autostage = false
['remote "storage"']
    url = s3://my-bucket
```


### Reproduce

<!--
Step list of how to reproduce the bug
-->


### Expected

<!--
A clear and concise description of what you expect to happen.
-->

### Environment information

<!--
This is required to ensure that we can reproduce the bug.
-->

**Output of `dvc doctor`:**

```console
$ dvc doctor
DVC version: 2.53.0 (pip)
-------------------------
Platform: Python 3.8.10 on Linux-5.15.0-69-generic-x86_64-with-glibc2.29
Subprojects:
        dvc_data = 0.47.1
        dvc_objects = 0.21.1
        dvc_render = 0.3.1
        dvc_task = 0.2.0
        scmrepo = 0.2.1
Supports:
        http (aiohttp = 3.8.4, aiohttp-retry = 2.8.3),
        https (aiohttp = 3.8.4, aiohttp-retry = 2.8.3),
        s3 (s3fs = 2023.3.0, boto3 = 1.24.59)
Cache types: hardlink, symlink
Cache directory: ext4 on /dev/nvme0n1p2
Caches: local
Remotes: s3
Workspace directory: ext4 on /dev/nvme0n1p2
Repo: dvc, git
Repo.site_cache_dir: /var/tmp/dvc/repo/bd4cb303de678027a3ce1969808057d7
```



**Additional Information (if any):**

<!--
Please check https://github.com/iterative/dvc/wiki/Debugging-DVC on ways to gather more information regarding the issue.

If applicable, please also provide a `--verbose` output of the command, eg: `dvc add --verbose`.
If the issue is regarding the performance, please attach the profiling information and the benchmark comparisons.
-->



Discussion:
Looks like a regression from https://github.com/iterative/dvc/pull/9250. cc @daavoo 
> Looks like a regression from #9250. cc @daavoo

Yep. We should respect the config option
In fact, it should not run in the context of repro, which is a bigger issue. I'll try to move it to exp run.

Resolving patch:
diff --git a/dvc/repo/experiments/executor/base.py b/dvc/repo/experiments/executor/base.py
--- a/dvc/repo/experiments/executor/base.py
+++ b/dvc/repo/experiments/executor/base.py
@@ -13,6 +13,7 @@
     Callable,
     Dict,
     Iterable,
+    Iterator,
     List,
     NamedTuple,
     Optional,
@@ -259,6 +260,12 @@ def _from_stash_entry(
             **kwargs,
         )
 
+    @classmethod
+    def _get_top_level_paths(cls, repo: "Repo") -> Iterable["str"]:
+        yield from _collect_top_level_metrics(repo)
+        yield from _collect_top_level_params(repo)
+        yield from repo.index._plot_sources  # pylint: disable=protected-access
+
     @classmethod
     def save(
         cls,
@@ -280,11 +287,7 @@ def save(
             os.chdir(dvc.root_dir)
 
         include_untracked = include_untracked or []
-        include_untracked.extend(_collect_top_level_metrics(dvc))
-        include_untracked.extend(_collect_top_level_params(dvc))
-        include_untracked.extend(
-            dvc.index._plot_sources  # pylint: disable=protected-access
-        )
+        include_untracked.extend(cls._get_top_level_paths(dvc))
         # dvc repro automatically stages dvc.lock. Running redundant `git add`
         # on it causes an error when exiting the detached head context.
         if LOCK_FILE in dvc.scm.untracked_files():
@@ -540,11 +543,19 @@ def filter_pipeline(stages):
                 info.name,
                 repro_force or checkpoint_reset,
             )
+
+            def after_repro():
+                paths = list(cls._get_top_level_paths(dvc))
+                if paths:
+                    logger.debug("Staging top-level files: %s", paths)
+                    dvc.scm_context.add(paths)
+
             stages = dvc_reproduce(
                 dvc,
                 *args,
                 on_unchanged=filter_pipeline,
                 checkpoint_func=checkpoint_func,
+                after_repro_callback=after_repro,
                 **kwargs,
             )
 
@@ -614,7 +625,7 @@ def _repro_dvc(  # noqa: C901
         log_errors: bool = True,
         copy_paths: Optional[List[str]] = None,
         **kwargs,
-    ):
+    ) -> Iterator["Repo"]:
         from dvc_studio_client.post_live_metrics import post_live_metrics
 
         from dvc.repo import Repo
diff --git a/dvc/repo/reproduce.py b/dvc/repo/reproduce.py
--- a/dvc/repo/reproduce.py
+++ b/dvc/repo/reproduce.py
@@ -3,8 +3,6 @@
 from typing import TYPE_CHECKING, Iterator, List
 
 from dvc.exceptions import DvcException, ReproductionError
-from dvc.repo.metrics.show import _collect_top_level_metrics
-from dvc.repo.params.show import _collect_top_level_params
 from dvc.repo.scm_context import scm_context
 from dvc.stage.exceptions import CheckpointKilledError
 
@@ -76,25 +74,15 @@ def _track_stage(stage: "Stage") -> None:
     return context.track_changed_files()
 
 
-def _track_top_level(repo: "Repo") -> None:
-    context = repo.scm_context
-    for metric_file in _collect_top_level_metrics(repo):
-        context.track_file(metric_file)
-    for param_file in _collect_top_level_params(repo):
-        context.track_file(param_file)
-    for plot_file in repo.index._plot_sources:  # pylint: disable=protected-access
-        context.track_file(plot_file)
-    context.track_changed_files()
-
-
 @locked
 @scm_context
-def reproduce(  # noqa: C901
+def reproduce(  # noqa: C901, PLR0912
     self: "Repo",
     targets=None,
     recursive=False,
     pipeline=False,
     all_pipelines=False,
+    after_repro_callback=None,
     **kwargs,
 ):
     from .graph import get_pipeline, get_pipelines
@@ -139,12 +127,18 @@ def reproduce(  # noqa: C901
             )
 
     result = _reproduce_stages(self.index.graph, list(stages), **kwargs)
-    _track_top_level(self)
+    if callable(after_repro_callback):
+        after_repro_callback()
     return result
 
 
 def _reproduce_stages(  # noqa: C901
-    graph, stages, downstream=False, single_item=False, on_unchanged=None, **kwargs
+    graph,
+    stages,
+    downstream=False,
+    single_item=False,
+    on_unchanged=None,
+    **kwargs,
 ):
     r"""Derive the evaluation of the given node for the given graph.
 


Test patch: