diff --git a/dvc/output.py b/dvc/output.py index ee1f89d31..c74524d53 100644 --- a/dvc/output.py +++ b/dvc/output.py @@ -709,7 +709,7 @@ class Output: except _CheckoutError as exc: raise CheckoutError(exc.paths, {}) # noqa: B904 - def commit(self, filter_info=None) -> None: + def commit(self, filter_info=None, relink=True) -> None: if not self.exists: raise self.DoesNotExistError(self) @@ -719,8 +719,11 @@ class Output: granular = ( self.is_dir_checksum and filter_info and filter_info != self.fs_path ) + # NOTE: trying to use hardlink during transfer only if we will be + # relinking later + hardlink = relink if granular: - obj = self._commit_granular_dir(filter_info) + obj = self._commit_granular_dir(filter_info, hardlink) else: staging, _, obj = build( self.cache, @@ -734,20 +737,21 @@ class Output: self.cache, {obj.hash_info}, shallow=False, - hardlink=True, + hardlink=hardlink, ) - self._checkout( - filter_info or self.fs_path, - self.fs, - obj, - self.cache, - relink=True, - state=self.repo.state, - prompt=prompt.confirm, - ) - self.set_exec() + if relink: + self._checkout( + filter_info or self.fs_path, + self.fs, + obj, + self.cache, + relink=True, + state=self.repo.state, + prompt=prompt.confirm, + ) + self.set_exec() - def _commit_granular_dir(self, filter_info) -> Optional["HashFile"]: + def _commit_granular_dir(self, filter_info, hardlink) -> Optional["HashFile"]: prefix = self.fs.path.parts(self.fs.path.relpath(filter_info, self.fs_path)) staging, _, save_obj = build( self.cache, @@ -764,7 +768,7 @@ class Output: self.cache, {save_obj.hash_info} | {oid for _, _, oid in save_obj}, shallow=True, - hardlink=True, + hardlink=hardlink, ) return checkout_obj diff --git a/dvc/repo/commit.py b/dvc/repo/commit.py index 6f70134ef..4ec2f6b7d 100644 --- a/dvc/repo/commit.py +++ b/dvc/repo/commit.py @@ -43,6 +43,7 @@ def commit( force=False, allow_missing=False, data_only=False, + relink=True, ): stages_info = [ info @@ -60,6 +61,10 @@ def commit( 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) + stage.commit( + filter_info=stage_info.filter_info, + allow_missing=allow_missing, + relink=relink, + ) stage.dump(update_pipeline=False) return [s.stage for s in stages_info] diff --git a/dvc/repo/experiments/queue/base.py b/dvc/repo/experiments/queue/base.py index 32d80bab2..82d806181 100644 --- a/dvc/repo/experiments/queue/base.py +++ b/dvc/repo/experiments/queue/base.py @@ -472,6 +472,7 @@ class BaseStashQueue(ABC): force=True, allow_missing=True, data_only=True, + relink=False, ) @staticmethod diff --git a/dvc/stage/__init__.py b/dvc/stage/__init__.py index 4d3b99075..a7ff66360 100644 --- a/dvc/stage/__init__.py +++ b/dvc/stage/__init__.py @@ -545,13 +545,13 @@ class Stage(params.StageParams): ) @rwlocked(write=["outs"]) - def commit(self, allow_missing=False, filter_info=None) -> None: + def commit(self, allow_missing=False, filter_info=None, **kwargs) -> None: from dvc.output import OutputDoesNotExistError link_failures = [] for out in self.filter_outs(filter_info): try: - out.commit(filter_info=filter_info) + out.commit(filter_info=filter_info, **kwargs) except OutputDoesNotExistError: if not (allow_missing or out.checkpoint): raise