Summary
In git-tree-reset.sh --apply, git clean -fdx runs unconditionally after git reset --hard, with no check on the reset's exit status. If the reset fails, the destructive clean still executes — a partial operation that deletes untracked/ignored files without the tree having been realigned.
Component
plugins/repo-hygiene/skills/clean/scripts/git-tree-reset.sh.
Root cause
184 git reset --hard "$UPSTREAM"
...
187 CLEAN_STDERR="$(git clean -fdx "${PRESERVE_ARGS[@]}" 2>&1 >/dev/null)"
The script runs under set -uo pipefail (no -e), and line 184's exit status is never inspected before line 187 runs. Any reset failure (the @{u} case in the companion issue, a locked index, a bad ref, an interrupted fetch) drops straight through to clean -fdx.
Evidence (this session)
The 6 repos that hit fatal: ambiguous argument '@{u}' at the reset step still proceeded to run git clean -fdx and reported AppliedClean: git clean -fdx (+1 preserve excludes). Net effect: cleaned but not reset.
Impact
Destructive clean -fdx executes in a state the reset was supposed to establish. For a tool whose contract is "reset to upstream then clean," running clean without a successful reset violates the invariant and can surprise the user (untracked work removed while the tree is not at the intended commit).
Expected
clean -fdx runs only if reset --hard succeeded. On reset failure: abort the apply, report the failure honestly, run no clean.
Acceptance criteria
Summary
In
git-tree-reset.sh --apply,git clean -fdxruns unconditionally aftergit reset --hard, with no check on the reset's exit status. If the reset fails, the destructive clean still executes — a partial operation that deletes untracked/ignored files without the tree having been realigned.Component
plugins/repo-hygiene/skills/clean/scripts/git-tree-reset.sh.Root cause
The script runs under
set -uo pipefail(no-e), and line 184's exit status is never inspected before line 187 runs. Any reset failure (the@{u}case in the companion issue, a locked index, a bad ref, an interrupted fetch) drops straight through toclean -fdx.Evidence (this session)
The 6 repos that hit
fatal: ambiguous argument '@{u}'at the reset step still proceeded to rungit clean -fdxand reportedAppliedClean: git clean -fdx (+1 preserve excludes). Net effect: cleaned but not reset.Impact
Destructive
clean -fdxexecutes in a state the reset was supposed to establish. For a tool whose contract is "reset to upstream then clean," running clean without a successful reset violates the invariant and can surprise the user (untracked work removed while the tree is not at the intended commit).Expected
clean -fdxruns only ifreset --hardsucceeded. On reset failure: abort the apply, report the failure honestly, run no clean.Acceptance criteria
AppliedReset:/AppliedClean:success lines emitted when the underlying command failed (see companion output-integrity issue).