Validate staged Go blobs in pre-commit gofmt check and include renames#56
Conversation
There was a problem hiding this comment.
Pull request overview
Updates the repo’s Git pre-commit hook to validate gofmt against staged Go file content (rather than the working tree) and to include renamed Go files in the formatting check.
Changes:
- Expands staged file selection to include renames via
--diff-filter=ACMRand limits to*.go. - Reads each staged blob into a temp file, formats a copy, and compares to detect staged formatting drift.
- Improves failure output with staged-file wording and guidance to reformat + re-stage.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
.githooks/pre-commit
Outdated
| if ! cmp -s "$orig" "$formatted"; then | ||
| UNFORMATTED="${UNFORMATTED}${file}\n" | ||
| fi | ||
|
|
||
| rm -f "$orig" "$formatted" | ||
| done <<EOF2 | ||
| $STAGED_GO | ||
| EOF2 | ||
|
|
||
| if [ -n "$UNFORMATTED" ]; then | ||
| echo "gofmt required on:" | ||
| echo "$UNFORMATTED" | ||
| echo "gofmt required on staged content:" | ||
| printf "%b" "$UNFORMATTED" |
There was a problem hiding this comment.
UNFORMATTED is built using \n escape sequences and printed with printf "%b" (lines 30, 40). If a filename contains backslashes, printf %b will interpret them as escapes and the output can be corrupted/misleading. Prefer accumulating real newlines (or a temp file) and printing with printf '%s\n' ... without %b escape processing.
.githooks/pre-commit
Outdated
| done <<EOF2 | ||
| $STAGED_GO | ||
| EOF2 |
There was a problem hiding this comment.
The here-doc body contains a leading space before $STAGED_GO (line 35). That causes the first staged path read by the loop to be prefixed with a space, so git show ":$file" won’t find the blob and the hook will silently skip the file (allowing unformatted code through). Remove the leading whitespace or feed the list to the loop in a way that doesn’t introduce indentation.
.githooks/pre-commit
Outdated
| orig=$(mktemp) | ||
| formatted=$(mktemp) |
There was a problem hiding this comment.
mktemp is invoked without a template (lines 15–16). This fails on macOS/BSD mktemp (template is required), which would make the hook ineffective (and potentially allow unformatted code to be committed). Use a portable mktemp form (e.g., pass an explicit template path under ${TMPDIR:-/tmp}) and handle failures explicitly.
| orig=$(mktemp) | |
| formatted=$(mktemp) | |
| orig=$(mktemp "${TMPDIR:-/tmp}/gofmt.orig.XXXXXX") || { | |
| echo "pre-commit: failed to create temporary file for original content" >&2 | |
| exit 1 | |
| } | |
| formatted=$(mktemp "${TMPDIR:-/tmp}/gofmt.formatted.XXXXXX") || { | |
| echo "pre-commit: failed to create temporary file for formatted content" >&2 | |
| rm -f "$orig" | |
| exit 1 | |
| } |
- Use portable mktemp with explicit template (macOS compat) - Pipe staged files instead of here-doc (no leading space bug) - Use temp file + cat instead of printf %b (no backslash escapes) - Clean up temp result file on exit Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Motivation
gofmtagainst the staged blob rather than the working-tree file.Rto the diff filter.Description
git diff --cached --name-only --diff-filter=ACMR -- '*.go'.git show :<file>into a temp file, rungofmt -won a copied temp file, and usecmp -sto detect formatting differences and collect unformatted staged paths.gofmt -w <files> && git add <files>.Testing
sh -n .githooks/pre-committo validate shell syntax and it succeeded.Codex Task