Skip to content

fix(pre-commit): skip format check when unstaged changes are present

38f435d
Select commit
Loading
Failed to load commit list.
Open

Add optional pre-commit hook for code formatting #5178

fix(pre-commit): skip format check when unstaged changes are present
38f435d
Select commit
Loading
Failed to load commit list.
@sentry/warden / warden: find-bugs completed May 5, 2026 in 48s

3 issues

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

High

Pre-commit hook silently auto-formats staged files, modifying tracked content without consent - `.githooks/pre-commit:22-24`

The hook runs dotnet format without --verify-no-changes, which mutates files in the working tree. Because the hook only checks git diff (unstaged changes) afterward, any formatting fixes applied by dotnet format will modify the working tree but the original (unformatted) staged content is still what gets committed. The user is told to git add -u and recommit, but if the working tree happens to match the index after formatting (e.g., file was already formatted), the hook exits 0 and an unformatted snapshot is committed. This contradicts the PR description which claims 'check-only mode' using --verify-no-changes.

Also found at:

  • .githooks/pre-commit:6-10

Medium

Filenames with spaces or special characters break the --include argument list - `.githooks/pre-commit:12-15`

The loop on lines 12-15 reads staged filenames via git diff --cached --name-only and passes them to dotnet format --include. git diff --name-only does not quote special characters by default unless core.quotePath is configured, and even with proper reading, filenames with spaces will be passed correctly to --include as separate args — but newer git versions or filenames containing quotes/backslashes produce C-style quoted output (e.g., "foo\tbar.cs") which would not match real paths. This can cause the hook to either miss files or fail unexpectedly.

Low

Suppressing dotnet format output hides real errors from developers - `.githooks/pre-commit:24`

Redirecting both stdout and stderr to /dev/null on line 24 means that genuine failures of dotnet format (e.g., missing SDK, project load errors, MSBuild failures) are silently swallowed. With set -e at the top, the script will then abort with no diagnostic, leaving developers unable to understand why their commit was rejected.


Duration: 44.7s · Tokens: 50.8k in / 2.8k out · Cost: $0.62 (+merge: $0.00)

Annotations

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

See this annotation in the file changed.

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

Pre-commit hook silently auto-formats staged files, modifying tracked content without consent

The hook runs `dotnet format` without `--verify-no-changes`, which mutates files in the working tree. Because the hook only checks `git diff` (unstaged changes) afterward, any formatting fixes applied by `dotnet format` will modify the working tree but the original (unformatted) staged content is still what gets committed. The user is told to `git add -u` and recommit, but if the working tree happens to match the index after formatting (e.g., file was already formatted), the hook exits 0 and an unformatted snapshot is committed. This contradicts the PR description which claims 'check-only mode' using `--verify-no-changes`.

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

See this annotation in the file changed.

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

[PJD-FYR] Pre-commit hook silently auto-formats staged files, modifying tracked content without consent (additional location)

The hook runs `dotnet format` without `--verify-no-changes`, which mutates files in the working tree. Because the hook only checks `git diff` (unstaged changes) afterward, any formatting fixes applied by `dotnet format` will modify the working tree but the original (unformatted) staged content is still what gets committed. The user is told to `git add -u` and recommit, but if the working tree happens to match the index after formatting (e.g., file was already formatted), the hook exits 0 and an unformatted snapshot is committed. This contradicts the PR description which claims 'check-only mode' using `--verify-no-changes`.

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

See this annotation in the file changed.

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

Filenames with spaces or special characters break the --include argument list

The loop on lines 12-15 reads staged filenames via `git diff --cached --name-only` and passes them to `dotnet format --include`. `git diff --name-only` does not quote special characters by default unless `core.quotePath` is configured, and even with proper reading, filenames with spaces will be passed correctly to `--include` as separate args — but newer git versions or filenames containing quotes/backslashes produce C-style quoted output (e.g., `"foo\tbar.cs"`) which would not match real paths. This can cause the hook to either miss files or fail unexpectedly.