Skip to content

Match pre-commit hook to CI formatting behavior

aa396a3
Select commit
Loading
Failed to load commit list.
Open

Add optional pre-commit hook for code formatting #5178

Match pre-commit hook to CI formatting behavior
aa396a3
Select commit
Loading
Failed to load commit list.
@sentry/warden / warden completed May 3, 2026 in 1m 1s

4 issues

High

Stashed unstaged changes are lost if `dotnet format` fails due to `set -e` - `.githooks/pre-commit:2-13`

The script uses set -e at the top, then stashes unstaged changes before running dotnet format. If dotnet format exits non-zero (e.g., build/compilation error, invalid project state), set -e causes immediate script termination, skipping the git stash pop block entirely. The developer's unstaged work-in-progress changes remain in the stash with no notification, appearing lost. This is a data-loss risk and unintended side effect on every commit attempt where formatting tooling errors occur.

Also found at:

  • .githooks/pre-commit:12-13
  • .githooks/pre-commit:22-24
`set -e` plus failed `dotnet format` causes silent abort leaving stash unrestored - `.githooks/pre-commit:11-13`

With set -e at the top, if dotnet format exits non-zero (e.g., compile error, missing SDK, network issue during restore), the script terminates immediately at line 12. The stash pop on lines 22-24 is never reached, leaving the developer's unstaged changes trapped in the stash with a confusing name. The user sees no error message because stdout/stderr are redirected to /dev/null.

Also found at:

  • .githooks/pre-commit:9-19

Medium

Glob pattern `./**/*OptionsSetup.cs` is shell-expanded before being passed to dotnet format - `.githooks/pre-commit:12-13`

Bash will expand ./**/*OptionsSetup.cs (with globstar potentially disabled) and ./modules before invoking dotnet format. Without shopt -s globstar, ** is treated as *, so the exclude argument passed to dotnet format may not match the intended files. Additionally, multiple matched files become multiple positional arguments, which --exclude may not accept. This means CI and the hook can diverge in what files they exclude, defeating the stated goal of matching CI exactly.

Stash pop conflict can leave repository in inconsistent state without notifying developer - `.githooks/pre-commit:22-24`

On line 23, git stash pop --quiet 2>/dev/null || true swallows any conflict that occurs when reapplying unstaged changes. If dotnet format modified files that the developer also had unstaged edits to, the pop will conflict and leave the stash in place — but the script reports success (or the formatting failure) and never tells the developer their unstaged work is still stashed.

4 skills analyzed
Skill Findings Duration Cost
code-review 1 46.0s $0.58
find-bugs 3 47.7s $0.44
gha-security-review 0 12.4s $0.44
security-review 0 7.3s $1.22

Duration: 1m 53s · Tokens: 235.7k in / 4.9k out · Cost: $2.69 (+merge: $0.00, +dedup: $0.00, +consolidate: $0.00)