Skip to content

Validate staged Go blobs in pre-commit gofmt check and include renames#56

Merged
JordanCoin merged 2 commits intomainfrom
codex/fix-pre-commit-hook-to-check-staged-content
Mar 27, 2026
Merged

Validate staged Go blobs in pre-commit gofmt check and include renames#56
JordanCoin merged 2 commits intomainfrom
codex/fix-pre-commit-hook-to-check-staged-content

Conversation

@JordanCoin
Copy link
Copy Markdown
Owner

Motivation

  • Prevent committing unformatted Go code by running gofmt against the staged blob rather than the working-tree file.
  • Ensure renamed Go files are included in the check by adding R to the diff filter.

Description

  • Update staged file selection to use git diff --cached --name-only --diff-filter=ACMR -- '*.go'.
  • For each staged path read the staged blob with git show :<file> into a temp file, run gofmt -w on a copied temp file, and use cmp -s to detect formatting differences and collect unformatted staged paths.
  • Improve failure output to list unformatted staged files and advise running gofmt -w <files> && git add <files>.

Testing

  • Ran sh -n .githooks/pre-commit to validate shell syntax and it succeeded.

Codex Task

Copilot AI review requested due to automatic review settings March 26, 2026 14:57
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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=ACMR and 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.

Comment on lines +29 to +40
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"
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +34 to +36
done <<EOF2
$STAGED_GO
EOF2
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +15 to +16
orig=$(mktemp)
formatted=$(mktemp)
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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
}

Copilot uses AI. Check for mistakes.
- 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>
@JordanCoin JordanCoin merged commit 98b3994 into main Mar 27, 2026
11 of 12 checks passed
@JordanCoin JordanCoin deleted the codex/fix-pre-commit-hook-to-check-staged-content branch March 27, 2026 01:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants