Skip to content

fix(pre-commit): ensure stashed changes are always restored

aed5d9a
Select commit
Loading
Failed to load commit list.
Open

Add optional pre-commit hook for code formatting #5178

fix(pre-commit): ensure stashed changes are always restored
aed5d9a
Select commit
Loading
Failed to load commit list.
@sentry/warden / warden: find-bugs completed May 3, 2026 in 44s

3 issues

find-bugs: Found 3 issues (1 high, 1 medium, 1 low)

High

Pre-commit hook silently modifies staged files via `dotnet format` - `.githooks/pre-commit:24-26`

dotnet format (without --verify-no-changes) rewrites files on disk. Because git stash push --keep-index leaves the staged content in the working tree, the format command modifies those staged files. The hook then detects the diff, aborts the commit, and the trap pops the stash — but the formatter's modifications to the working tree are NOT reverted. The developer's working copy now contains formatter changes they never asked for, mixed with their original edits, and on the next git add -u/commit they will commit formatter output silently. The PR description claims the hook uses --verify-no-changes (check-only), but the actual script does not.

Also found at:

  • .githooks/pre-commit:25-26

Medium

Stash detection by message can match unrelated stashes and miss empty stashes - `.githooks/pre-commit:10-16`

git stash push --keep-index creates no stash entry when there are no unstaged changes (and exits 0 due to || true). The later git stash list | grep -q "$STASH_NAME" correctly skips popping in that case, but the pattern match is a substring search against git stash list output, which could be matched by an unrelated user stash whose message happens to contain pre-commit-<timestamp> (unlikely but possible). More importantly, on a stash-conflict pop failure, the script tells the user to run git stash pop, but does not identify which stash to pop — the user may have multiple stashes and pop the wrong one.

Low

setup-hooks.sh does not ensure execute permission on hook script - `scripts/setup-hooks.sh:7`

The setup script configures core.hooksPath but does not ensure that .githooks/pre-commit is executable. If the file is checked out without the executable bit (e.g., on systems where git's filemode is not preserved or the file was added without +x), the pre-commit hook will silently fail to run, defeating the purpose of the hook. Adding chmod +x .githooks/pre-commit in the setup script guarantees the hook runs as intended.


Duration: 38.8s · Tokens: 50.1k in / 2.9k out · Cost: $0.43 (+merge: $0.00)

Annotations

Check failure on line 26 in .githooks/pre-commit

See this annotation in the file changed.

@sentry-warden sentry-warden / warden: find-bugs

Pre-commit hook silently modifies staged files via `dotnet format`

`dotnet format` (without `--verify-no-changes`) rewrites files on disk. Because `git stash push --keep-index` leaves the staged content in the working tree, the format command modifies those staged files. The hook then detects the diff, aborts the commit, and the trap pops the stash — but the formatter's modifications to the working tree are NOT reverted. The developer's working copy now contains formatter changes they never asked for, mixed with their original edits, and on the next `git add -u`/commit they will commit formatter output silently. The PR description claims the hook uses `--verify-no-changes` (check-only), but the actual script does not.

Check failure on line 26 in .githooks/pre-commit

See this annotation in the file changed.

@sentry-warden sentry-warden / warden: find-bugs

[96L-H56] Pre-commit hook silently modifies staged files via `dotnet format` (additional location)

`dotnet format` (without `--verify-no-changes`) rewrites files on disk. Because `git stash push --keep-index` leaves the staged content in the working tree, the format command modifies those staged files. The hook then detects the diff, aborts the commit, and the trap pops the stash — but the formatter's modifications to the working tree are NOT reverted. The developer's working copy now contains formatter changes they never asked for, mixed with their original edits, and on the next `git add -u`/commit they will commit formatter output silently. The PR description claims the hook uses `--verify-no-changes` (check-only), but the actual script does not.

Check warning on line 16 in .githooks/pre-commit

See this annotation in the file changed.

@sentry-warden sentry-warden / warden: find-bugs

Stash detection by message can match unrelated stashes and miss empty stashes

`git stash push --keep-index` creates no stash entry when there are no unstaged changes (and exits 0 due to `|| true`). The later `git stash list | grep -q "$STASH_NAME"` correctly skips popping in that case, but the pattern match is a substring search against `git stash list` output, which could be matched by an unrelated user stash whose message happens to contain `pre-commit-<timestamp>` (unlikely but possible). More importantly, on a stash-conflict pop failure, the script tells the user to run `git stash pop`, but does not identify which stash to pop — the user may have multiple stashes and pop the wrong one.