Implementation:Iterative Dvc Repo Move
| Knowledge Sources | |
|---|---|
| Domains | Data_Management, File_Operations |
| Last Updated | 2026-02-10 10:00 GMT |
Overview
Repo_Move provides functionality for renaming DVC-tracked output files and updating their associated .dvc stage files accordingly. It is implemented in dvc/repo/move.py (102 lines) and exposes a single public function move().
from dvc.repo.move import move
This function only works with outputs generated by dvc add or dvc import (data sources). It will not move outputs that are produced by pipeline stages.
Public Function
move()
Renames a DVC output file and updates the corresponding .dvc stage file to reflect the change.
Signature:
@locked
@scm_context
def move(self: "Repo", from_path: str, to_path: str) -> tuple[Stage, Stage]:
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
self |
Repo |
required | The DVC repository instance |
from_path |
str |
required | Path of the file to move |
to_path |
str |
required | Destination path |
Return value: A tuple of (old_stage, new_stage). If the .dvc file was renamed, these are different stage objects; otherwise they are the same.
Exceptions:
dvc.exceptions.MoveNotDataSourceError-- raised if the output belongs to a pipeline stage rather than a data source
Decorators:
@locked-- acquires the repo-level lock before execution@scm_context-- manages SCM (Git) tracking of changed files
Execution Flow
- The function loads the
from_pathas an output object and verifies it uses the local protocol. - It resolves
to_pathvia_expand_target_path(), appending the source basename ifto_pathis an existing directory. - The output is looked up in the repository via
self.find_outs_by_path()to find the associated stage. - If the stage is not a data source (
dvc add/dvc import), aMoveNotDataSourceErroris raised. - If the stage file name matches the output name (e.g.,
helloandhello.dvc), a new stage is created with a new.dvcfile at the destination, and the old.dvcfile is removed. - If the names differ, the existing stage is reused and only the output path within it is updated.
- Dependencies with relative local paths are re-adjusted to be relative to the new stage working directory.
- The output's
move()method is called to physically relocate the data. - The stage's MD5 is recomputed and the stage is dumped (saved) to disk.
Example
# Given: hello (data file) + hello.dvc (stage file)
$ dvc move hello greetings
# Result: greetings (data file) + greetings.dvc (stage file)
Internal Functions
_expand_target_path()
If to_path is an existing directory, appends the basename of from_path to it. Otherwise returns to_path unchanged.
def _expand_target_path(from_path, to_path):
if os.path.isdir(to_path):
return os.path.join(to_path, os.path.basename(from_path))
return to_path
Key Design Decisions
- Data source restriction: The function explicitly rejects moves of pipeline stage outputs via
MoveNotDataSourceError. This prevents breaking pipeline reproducibility, since pipeline outputs are defined by their stage dependencies. - Stage file co-renaming: When the
.dvcfile shares its name with the output (the commondvc addpattern), both are renamed atomically. This preserves the naming convention. - Dependency path adjustment: Local relative dependency paths are recalculated relative to the new stage working directory to maintain correct resolution.
- StageFileAlreadyExistsError re-raise: The error is caught and re-raised without the
--forcehint to avoid suggesting force-overwrite for move operations.
Dependencies
dvc.repo.locked-- repository lock decoratordvc.repo.scm_context.scm_context-- SCM tracking decoratordvc.output-- output loading and serializationdvc.dependency-- dependency loading and serializationdvc.dvcfile.DVC_FILE_SUFFIX-- the.dvcfile extension constantdvc.stage.Stage-- stage creation and managementdvc_objects.fs.local.LocalFileSystem-- local filesystem type checking