Skip to content

fix(pre-commit): improve stash conflict guidance

1c00577
Select commit
Loading
Failed to load commit list.
Open

Add optional pre-commit hook for code formatting #5178

fix(pre-commit): improve stash conflict guidance
1c00577
Select commit
Loading
Failed to load commit list.
@sentry/warden / warden: code-review completed May 3, 2026 in 42s

3 issues

code-review: Found 3 issues (1 high, 2 medium)

High

`set -e` causes script to exit before formatting failure path runs, leaving stash unrestored on dotnet format errors - `.githooks/pre-commit:29-30`

The script uses set -e combined with git stash push --keep-index. If dotnet format exits non-zero (e.g., build failure, restore issue, or tooling error), set -e aborts the script immediately. While the EXIT trap will still fire and attempt to restore the stash, the script never reaches the diff check or the user-facing error message — developers get a silent/cryptic failure with output redirected to /dev/null 2>&1, making it impossible to diagnose why the hook failed. Combined with 2>&1 > /dev/null, real formatter errors are completely swallowed.

Medium

Unquoted `./**/*OptionsSetup.cs` glob is expanded by bash, not passed to dotnet format - `.githooks/pre-commit:30`

The --exclude argument ./**/*OptionsSetup.cs is unquoted, so bash expands it before passing to dotnet format. Without shopt -s globstar, ** behaves as a single * and won't recurse; with globstar enabled it expands to a list of paths that are passed as multiple arguments. Either way, the behavior diverges from CI (which presumably passes the literal pattern) and the exclude may not match the intended files, causing the hook to fail commits over files that CI ignores.

`dotnet format` runs against entire working tree, not just staged changes, so unrelated formatting issues block commits - `.githooks/pre-commit:26-34`

git stash push --keep-index stashes unstaged changes, leaving staged changes in the working tree — but the working tree still contains all other tracked files. dotnet format then scans the entire solution and may reformat files that the developer didn't touch (e.g., pre-existing formatting drift on unrelated files). The hook will then fail the commit even though the staged diff is clean, blocking commits for issues outside the developer's change scope.


Duration: 38.3s · Tokens: 49.9k in / 2.2k out · Cost: $0.57 (+merge: $0.00)

Annotations

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

See this annotation in the file changed.

@sentry-warden sentry-warden / warden: code-review

`set -e` causes script to exit before formatting failure path runs, leaving stash unrestored on dotnet format errors

The script uses `set -e` combined with `git stash push --keep-index`. If `dotnet format` exits non-zero (e.g., build failure, restore issue, or tooling error), `set -e` aborts the script immediately. While the EXIT trap will still fire and attempt to restore the stash, the script never reaches the diff check or the user-facing error message — developers get a silent/cryptic failure with output redirected to `/dev/null 2>&1`, making it impossible to diagnose why the hook failed. Combined with `2>&1 > /dev/null`, real formatter errors are completely swallowed.

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

See this annotation in the file changed.

@sentry-warden sentry-warden / warden: code-review

Unquoted `./**/*OptionsSetup.cs` glob is expanded by bash, not passed to dotnet format

The `--exclude` argument `./**/*OptionsSetup.cs` is unquoted, so bash expands it before passing to `dotnet format`. Without `shopt -s globstar`, `**` behaves as a single `*` and won't recurse; with globstar enabled it expands to a list of paths that are passed as multiple arguments. Either way, the behavior diverges from CI (which presumably passes the literal pattern) and the exclude may not match the intended files, causing the hook to fail commits over files that CI ignores.

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

See this annotation in the file changed.

@sentry-warden sentry-warden / warden: code-review

`dotnet format` runs against entire working tree, not just staged changes, so unrelated formatting issues block commits

`git stash push --keep-index` stashes unstaged changes, leaving staged changes in the working tree — but the working tree still contains all other tracked files. `dotnet format` then scans the entire solution and may reformat files that the developer didn't touch (e.g., pre-existing formatting drift on unrelated files). The hook will then fail the commit even though the staged diff is clean, blocking commits for issues outside the developer's change scope.