prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  `exp run`: data gets re-imported on every call
  # Bug Report
  
  ## Description
  
  When a pipeline uses an imported data file (with `dvc import`), the data gets cloned(?) and hashed every time `dvc exp run` is called.
  
  ### Reproduce
  
  1. dvc import git@github.com:iterative/dataset-registry.git use-cases/cats-dogs
  2. dvc stage add -n foo -d cats-dogs echo foo
  3. dvc exp run
  
  ### Expected
  
  When using `dvc repro` the imported data doesn't get re-hashed. I would expect `dvc exp run` to behave the same.
  
  ### Environment information
  
  **Output of `dvc doctor`:**
  
  ```console
  $ dvc doctor
  DVC version: 2.6.3 (pip)
  ---------------------------------
  Platform: Python 3.9.6 on macOS-10.16-x86_64-i386-64bit
  Supports:
          gdrive (pydrive2 = 1.9.1),
          http (requests = 2.26.0),
          https (requests = 2.26.0)
  Cache types: reflink, hardlink, symlink
  Cache directory: apfs on /dev/disk1s1s1
  Caches: local
  Remotes: None
  Workspace directory: apfs on /dev/disk1s1s1
  Repo: dvc, git
  ```
  
  **Additional Information (if any):**
  
  ```console
  $ dvc repro -v
  2021-08-25 11:11:55,186 DEBUG: Computed stage: 'cats-dogs.dvc' md5: '5a135b297ee3c96465ce4b320f44fb8b'
  'cats-dogs.dvc' didn't change, skipping
  Stage 'foo' didn't change, skipping
  Data and pipelines are up to date.
  ```
  
  ```console
  $ dvc exp run -v
  2021-08-25 11:12:15,672 DEBUG: Detaching HEAD at 'HEAD'               
  2021-08-25 11:12:15,690 DEBUG: Stashing workspace
  2021-08-25 11:12:15,700 DEBUG: No changes to stash
  2021-08-25 11:12:15,749 DEBUG: Creating external repo git@github.com:iterative/dataset-registry.git@ca140591a21c6d75a7057d1e2eb3f51d3115c5f5
  2021-08-25 11:12:15,749 DEBUG: erepo: git clone 'git@github.com:iterative/dataset-registry.git' to a temporary dir
  Computing file/dir hashes (only done once)  
  . . .                                                                         
  ```
  
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `dvc/repo/commit.py`
  Content:
  ```
  1 from dvc import prompt
  2 
  3 from . import locked
  4 
  5 
  6 def _prepare_message(stage, changes):
  7     changed_deps, changed_outs, changed_stage = changes
  8     if changed_deps and changed_outs:
  9         msg = "dependencies {deps} and outputs {outs} of {stage} changed."
  10     elif changed_deps:
  11         msg = "dependencies {deps} of {stage} changed."
  12     elif changed_outs:
  13         msg = "outputs {outs} of {stage} changed."
  14     else:
  15         msg = "{stage_changed}"
  16 
  17     msg += " Are you sure you want to commit it?"
  18 
  19     kw = {
  20         "stage": stage,
  21         "deps": changed_deps,
  22         "outs": changed_outs,
  23         "stage_changed": changed_stage,
  24     }
  25     return msg.format_map(kw)
  26 
  27 
  28 def prompt_to_commit(stage, changes, force=False):
  29     from dvc.stage.exceptions import StageCommitError
  30 
  31     if not (force or prompt.confirm(_prepare_message(stage, changes))):
  32         raise StageCommitError(
  33             "unable to commit changed {}. Use `-f|--force` to "
  34             "force.".format(stage)
  35         )
  36 
  37 
  38 @locked
  39 def commit(
  40     self,
  41     target,
  42     with_deps=False,
  43     recursive=False,
  44     force=False,
  45     allow_missing=False,
  46     data_only=False,
  47 ):
  48     from dvc.dvcfile import Dvcfile
  49 
  50     stages_info = [
  51         info
  52         for info in self.stage.collect_granular(
  53             target, with_deps=with_deps, recursive=recursive
  54         )
  55         if not data_only or info.stage.is_data_source
  56     ]
  57     for stage_info in stages_info:
  58         stage = stage_info.stage
  59         changes = stage.changed_entries()
  60         if any(changes):
  61             prompt_to_commit(stage, changes, force=force)
  62             stage.save(allow_missing=allow_missing)
  63         stage.commit(
  64             filter_info=stage_info.filter_info, allow_missing=allow_missing
  65         )
  66 
  67         Dvcfile(self, stage.path).dump(stage, update_pipeline=False)
  68     return [s.stage for s in stages_info]
  69
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/dvc/repo/commit.py b/dvc/repo/commit.py
  --- a/dvc/repo/commit.py
  +++ b/dvc/repo/commit.py
  @@ -56,10 +56,13 @@
       ]
       for stage_info in stages_info:
           stage = stage_info.stage
  -        changes = stage.changed_entries()
  -        if any(changes):
  -            prompt_to_commit(stage, changes, force=force)
  +        if force:
               stage.save(allow_missing=allow_missing)
  +        else:
  +            changes = stage.changed_entries()
  +            if any(changes):
  +                prompt_to_commit(stage, changes, force=force)
  +                stage.save(allow_missing=allow_missing)
           stage.commit(
               filter_info=stage_info.filter_info, allow_missing=allow_missing
           )
  
verification_info: {"golden_diff": "diff --git a/dvc/repo/commit.py b/dvc/repo/commit.py\n--- a/dvc/repo/commit.py\n+++ b/dvc/repo/commit.py\n@@ -56,10 +56,13 @@\n     ]\n     for stage_info in stages_info:\n         stage = stage_info.stage\n-        changes = stage.changed_entries()\n-        if any(changes):\n-            prompt_to_commit(stage, changes, force=force)\n+        if force:\n             stage.save(allow_missing=allow_missing)\n+        else:\n+            changes = stage.changed_entries()\n+            if any(changes):\n+                prompt_to_commit(stage, changes, force=force)\n+                stage.save(allow_missing=allow_missing)\n         stage.commit(\n             filter_info=stage_info.filter_info, allow_missing=allow_missing\n         )\n", "issue": "`exp run`: data gets re-imported on every call\n# Bug Report\r\n\r\n## Description\r\n\r\nWhen a pipeline uses an imported data file (with `dvc import`), the data gets cloned(?) and hashed every time `dvc exp run` is called.\r\n\r\n### Reproduce\r\n\r\n1. dvc import git@github.com:iterative/dataset-registry.git use-cases/cats-dogs\r\n2. dvc stage add -n foo -d cats-dogs echo foo\r\n3. dvc exp run\r\n\r\n### Expected\r\n\r\nWhen using `dvc repro` the imported data doesn't get re-hashed. I would expect `dvc exp run` to behave the same.\r\n\r\n### Environment information\r\n\r\n**Output of `dvc doctor`:**\r\n\r\n```console\r\n$ dvc doctor\r\nDVC version: 2.6.3 (pip)\r\n---------------------------------\r\nPlatform: Python 3.9.6 on macOS-10.16-x86_64-i386-64bit\r\nSupports:\r\n        gdrive (pydrive2 = 1.9.1),\r\n        http (requests = 2.26.0),\r\n        https (requests = 2.26.0)\r\nCache types: reflink, hardlink, symlink\r\nCache directory: apfs on /dev/disk1s1s1\r\nCaches: local\r\nRemotes: None\r\nWorkspace directory: apfs on /dev/disk1s1s1\r\nRepo: dvc, git\r\n```\r\n\r\n**Additional Information (if any):**\r\n\r\n```console\r\n$ dvc repro -v\r\n2021-08-25 11:11:55,186 DEBUG: Computed stage: 'cats-dogs.dvc' md5: '5a135b297ee3c96465ce4b320f44fb8b'\r\n'cats-dogs.dvc' didn't change, skipping\r\nStage 'foo' didn't change, skipping\r\nData and pipelines are up to date.\r\n```\r\n\r\n```console\r\n$ dvc exp run -v\r\n2021-08-25 11:12:15,672 DEBUG: Detaching HEAD at 'HEAD'               \r\n2021-08-25 11:12:15,690 DEBUG: Stashing workspace\r\n2021-08-25 11:12:15,700 DEBUG: No changes to stash\r\n2021-08-25 11:12:15,749 DEBUG: Creating external repo git@github.com:iterative/dataset-registry.git@ca140591a21c6d75a7057d1e2eb3f51d3115c5f5\r\n2021-08-25 11:12:15,749 DEBUG: erepo: git clone 'git@github.com:iterative/dataset-registry.git' to a temporary dir\r\nComputing file/dir hashes (only done once)  \r\n. . .                                                                         \r\n```\r\n\r\n\n", "before_files": [{"content": "from dvc import prompt\n\nfrom . import locked\n\n\ndef _prepare_message(stage, changes):\n    changed_deps, changed_outs, changed_stage = changes\n    if changed_deps and changed_outs:\n        msg = \"dependencies {deps} and outputs {outs} of {stage} changed.\"\n    elif changed_deps:\n        msg = \"dependencies {deps} of {stage} changed.\"\n    elif changed_outs:\n        msg = \"outputs {outs} of {stage} changed.\"\n    else:\n        msg = \"{stage_changed}\"\n\n    msg += \" Are you sure you want to commit it?\"\n\n    kw = {\n        \"stage\": stage,\n        \"deps\": changed_deps,\n        \"outs\": changed_outs,\n        \"stage_changed\": changed_stage,\n    }\n    return msg.format_map(kw)\n\n\ndef prompt_to_commit(stage, changes, force=False):\n    from dvc.stage.exceptions import StageCommitError\n\n    if not (force or prompt.confirm(_prepare_message(stage, changes))):\n        raise StageCommitError(\n            \"unable to commit changed {}. Use `-f|--force` to \"\n            \"force.\".format(stage)\n        )\n\n\n@locked\ndef commit(\n    self,\n    target,\n    with_deps=False,\n    recursive=False,\n    force=False,\n    allow_missing=False,\n    data_only=False,\n):\n    from dvc.dvcfile import Dvcfile\n\n    stages_info = [\n        info\n        for info in self.stage.collect_granular(\n            target, with_deps=with_deps, recursive=recursive\n        )\n        if not data_only or info.stage.is_data_source\n    ]\n    for stage_info in stages_info:\n        stage = stage_info.stage\n        changes = stage.changed_entries()\n        if any(changes):\n            prompt_to_commit(stage, changes, force=force)\n            stage.save(allow_missing=allow_missing)\n        stage.commit(\n            filter_info=stage_info.filter_info, allow_missing=allow_missing\n        )\n\n        Dvcfile(self, stage.path).dump(stage, update_pipeline=False)\n    return [s.stage for s in stages_info]\n", "path": "dvc/repo/commit.py"}], "after_files": [{"content": "from dvc import prompt\n\nfrom . import locked\n\n\ndef _prepare_message(stage, changes):\n    changed_deps, changed_outs, changed_stage = changes\n    if changed_deps and changed_outs:\n        msg = \"dependencies {deps} and outputs {outs} of {stage} changed.\"\n    elif changed_deps:\n        msg = \"dependencies {deps} of {stage} changed.\"\n    elif changed_outs:\n        msg = \"outputs {outs} of {stage} changed.\"\n    else:\n        msg = \"{stage_changed}\"\n\n    msg += \" Are you sure you want to commit it?\"\n\n    kw = {\n        \"stage\": stage,\n        \"deps\": changed_deps,\n        \"outs\": changed_outs,\n        \"stage_changed\": changed_stage,\n    }\n    return msg.format_map(kw)\n\n\ndef prompt_to_commit(stage, changes, force=False):\n    from dvc.stage.exceptions import StageCommitError\n\n    if not (force or prompt.confirm(_prepare_message(stage, changes))):\n        raise StageCommitError(\n            \"unable to commit changed {}. Use `-f|--force` to \"\n            \"force.\".format(stage)\n        )\n\n\n@locked\ndef commit(\n    self,\n    target,\n    with_deps=False,\n    recursive=False,\n    force=False,\n    allow_missing=False,\n    data_only=False,\n):\n    from dvc.dvcfile import Dvcfile\n\n    stages_info = [\n        info\n        for info in self.stage.collect_granular(\n            target, with_deps=with_deps, recursive=recursive\n        )\n        if not data_only or info.stage.is_data_source\n    ]\n    for stage_info in stages_info:\n        stage = stage_info.stage\n        if force:\n            stage.save(allow_missing=allow_missing)\n        else:\n            changes = stage.changed_entries()\n            if any(changes):\n                prompt_to_commit(stage, changes, force=force)\n                stage.save(allow_missing=allow_missing)\n        stage.commit(\n            filter_info=stage_info.filter_info, allow_missing=allow_missing\n        )\n\n        Dvcfile(self, stage.path).dump(stage, update_pipeline=False)\n    return [s.stage for s in stages_info]\n", "path": "dvc/repo/commit.py"}]}