2026-09-01 14:00:09,035 DEBUG: v3.67.1 (pip), CPython 3.14.2 on Linux-7.1.5-76070105-generic-x86_64-with-glibc2.39
2026-09-01 14:00:09,035 DEBUG: command: /home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/bin/dvc repro -v
2026-09-01 14:00:09,412 DEBUG: Output 'output/out1' of stage: 'stage1' changed because it is 'not in cache'.
2026-09-01 14:00:09,412 DEBUG: stage: 'stage1' changed.
2026-09-01 14:00:09,415 DEBUG: Removing output 'output/out1' of stage: 'stage1'.
2026-09-01 14:00:09,415 DEBUG: Removing '/home/joostmeulenbeld/git/mwe_dvc_noignore/output/out1'
Running stage 'stage1':
> mkdir -p output
> echo ok > output/out1
2026-09-01 14:00:09,428 DEBUG: Added '/home/joostmeulenbeld/git/mwe_dvc_noignore/output/out1' to gitignore file.
2026-09-01 14:00:09,437 DEBUG: Computed stage: 'stage1' md5: 'fc98065f95e8b773dcd45d4d3e4fb0f8'
2026-09-01 14:00:09,441 DEBUG: Preparing to transfer data from 'memory://dvc-staging-md5/cc0bb25b96409904853d0280d6caaf899e5e170c9701e667d661ed11eed04c8e' to '/home/joostmeulenbeld/git/mwe_dvc_noignore/.dvc/cache/files/md5'
2026-09-01 14:00:09,441 DEBUG: Preparing to collect status from '/home/joostmeulenbeld/git/mwe_dvc_noignore/.dvc/cache/files/md5'
2026-09-01 14:00:09,441 DEBUG: Collecting status from '/home/joostmeulenbeld/git/mwe_dvc_noignore/.dvc/cache/files/md5'
2026-09-01 14:00:09,442 DEBUG: Preparing to collect status from 'memory://dvc-staging-md5/cc0bb25b96409904853d0280d6caaf899e5e170c9701e667d661ed11eed04c8e'
2026-09-01 14:00:09,443 DEBUG: link type reflink is not available ([Errno 95] no more link types left to try out)
2026-09-01 14:00:09,443 DEBUG: Removing '/home/joostmeulenbeld/git/mwe_dvc_noignore/output/.svn_L2PF3RMz-pj5F5cSVw.tmp'
2026-09-01 14:00:09,444 DEBUG: Removing '/home/joostmeulenbeld/git/mwe_dvc_noignore/output/.svn_L2PF3RMz-pj5F5cSVw.tmp'
2026-09-01 14:00:09,444 DEBUG: Removing '/home/joostmeulenbeld/git/mwe_dvc_noignore/.dvc/cache/files/md5/.Tsjlf-3HNp_ytWCDNf1QMw.tmp'
2026-09-01 14:00:09,444 DEBUG: Removing '/home/joostmeulenbeld/git/mwe_dvc_noignore/output/out1'
2026-09-01 14:00:09,467 DEBUG: stage: 'stage1' was reproduced
2026-09-01 14:00:09,475 DEBUG: 'cmd' of stage: 'stage2' has changed.
2026-09-01 14:00:09,475 DEBUG: stage: 'stage2' changed.
2026-09-01 14:00:09,476 DEBUG: 'cmd' of stage: 'stage2' has changed.
2026-09-01 14:00:09,476 DEBUG: stage: 'stage2' changed.
2026-09-01 14:00:09,477 DEBUG: Removing output 'output/out2' of stage: 'stage2'.
2026-09-01 14:00:09,477 DEBUG: Removing '/home/joostmeulenbeld/git/mwe_dvc_noignore/output/out2'
2026-09-01 14:00:09,479 DEBUG: 'cmd' of stage: 'stage2' has changed.
Running stage 'stage2':
> cp output/out1 output/out2
> exit 1
2026-09-01 14:00:09,501 DEBUG: Removing '/home/joostmeulenbeld/git/mwe_dvc_noignore/output/out1' from gitignore file.
2026-09-01 14:00:09,502 ERROR: failed to reproduce 'stage2': failed to run: exit 1, exited with 1
Traceback (most recent call last):
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/repo/reproduce.py", line 187, in _reproduce
ret = repro_fn(stage, upstream=upstream, force=force_stage, **kwargs)
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/repo/reproduce.py", line 117, in _reproduce_stage
ret = stage.reproduce(**kwargs)
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/funcy/decorators.py", line 47, in wrapper
return deco(call, *dargs, **dkwargs)
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/stage/decorators.py", line 44, in rwlocked
return call()
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/funcy/decorators.py", line 68, in __call__
return self._func(*self._args, **self._kwargs)
~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/stage/__init__.py", line 448, in reproduce
self.run(**kwargs)
~~~~~~~~^^^^^^^^^^
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/funcy/decorators.py", line 47, in wrapper
return deco(call, *dargs, **dkwargs)
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/stage/decorators.py", line 44, in rwlocked
return call()
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/funcy/decorators.py", line 68, in __call__
return self._func(*self._args, **self._kwargs)
~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/stage/__init__.py", line 601, in run
self._run_stage(dry, force, **kwargs)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/funcy/decorators.py", line 47, in wrapper
return deco(call, *dargs, **dkwargs)
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/stage/decorators.py", line 44, in rwlocked
return call()
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/funcy/decorators.py", line 68, in __call__
return self._func(*self._args, **self._kwargs)
~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/stage/__init__.py", line 628, in _run_stage
return run_stage(self, dry, force, **kwargs)
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/stage/run.py", line 182, in run_stage
run(stage, dry=dry, run_env=run_env)
~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/stage/decorators.py", line 53, in wrapper
ret = f(stage, *args, **kwargs)
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/stage/run.py", line 153, in cmd_run
_run(executable, cmd, **kwargs)
~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/stage/run.py", line 133, in _run
raise StageCmdFailedError(cmd, p.returncode)
dvc.stage.exceptions.StageCmdFailedError: failed to run: exit 1, exited with 1
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/cli/__init__.py", line 212, in main
ret = cmd.do_run()
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/cli/command.py", line 30, in do_run
return self.run()
~~~~~~~~^^
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/commands/repro.py", line 11, in run
stages = self.repo.reproduce(**self._common_kwargs, **self._repro_kwargs)
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/repo/__init__.py", line 59, in wrapper
return f(repo, *args, **kwargs)
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/repo/scm_context.py", line 150, in run
return method(repo, *args, **kw)
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/repo/reproduce.py", line 248, in reproduce
return _reproduce(steps, graph=graph, on_error=on_error or "fail", **kwargs)
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/repo/reproduce.py", line 191, in _reproduce
_raise_error(exc, stage)
~~~~~~~~~~~~^^^^^^^^^^^^
File "/home/joostmeulenbeld/.cache/uv/archive-v0/KgpsAQHnaEG055oR/lib/python3.14/site-packages/dvc/repo/reproduce.py", line 155, in _raise_error
raise ReproductionError(f"failed to reproduce{segment} {names}") from exc
dvc.exceptions.ReproductionError: failed to reproduce 'stage2'
2026-09-01 14:00:09,506 DEBUG: Analytics is enabled.
2026-09-01 14:00:09,547 DEBUG: Trying to spawn ['daemon', 'analytics', '/tmp/tmpjk5e55cl', '-v']
2026-09-01 14:00:09,555 DEBUG: Spawned ['daemon', 'analytics', '/tmp/tmpjk5e55cl', '-v'] with pid 112440
Bug Report
Description
When
dvc reproruns a pipeline with multiple stages and a later stage fails,.gitignoreentries added for outputs of earlier successfully completed stages are rolled back.For comparison, when the same pipeline completes successfully, DVC correctly creates
output/.gitignorecontaining:If
stage2is changed to fail after creating its output, the files are still created,dvc.lockis updated, but the.gitignoreentries are not created. After fixing thestage2command and rerunningdvc repro, the outs ofstage2are correctly added to the.gitignorebutstage1.The way I fix that now is by manually typing the succesfully run outputs into the
.gitignore, which is cumbersome. Maybe there is a command to do it that I don't know about? But anyway, to me it would make more sense if theReproduce
Start in an empty Git repository:
Create the following
dvc.yaml:Run:
$ uvx dvc repro dvc.yamlAs expected,
dvc reprofails because ofexit 1.Both output files have nevertheless been created:
However, the ignore rules for the outputs are not created in
output/.gitignore. When running with-vit states explicitly that the.gitignoreentry ofout1is removed. I guess this technically means this is not a bug but intended behavior, but it is counterintuitive and counterproductive for normal use.As a control, removing the following command from
stage2:- exit 1and running the same pipeline successfully (in a clean repo state) results in:
being added to
output/.gitignore.Expected
The
.gitignoreentry foroutput/out1should be created.stage1completed successfully, its output remains in the workspace, and thedvc.lockfile is updated succesfully. A failure in the downstreamstage2should not roll back Git ignore state belonging to the already completed stage.Environment information
Output of
dvc doctor:Additional Information (if any):
`dvc repro -v` run