Pre-commit Hooks & Review Checklists
Pre-commit hooks run fast quality checks on every commit.
Search across all documentation pages
Pre-commit hooks run fast quality checks on every commit.
PR review checklists capture what automation cannot see: API shape, failure modes, and operability.
Together they shorten feedback loops without replacing CI as the merge authority.
Quick-reference recipe card - copy-paste ready.
# scripts/pre-commit.sh
#!/usr/bin/env bash
set -euo pipefail
changed=$(git diff --cached --name-only --diff-filter=ACM | grep '\.go$' || true)
[ -z "$changed" ] && exit 0
echo "$changed" | xargs goimports -local example.com/mycorp -w
echo "$changed" | xargs gofmt -s -w
echo "$changed" | xargs go vet
go test ./...chmod +x scripts/pre-commit.sh
ln -sf ../../scripts/pre-commit.sh .git/hooks/pre-commitWhen to reach for this:
make check is not yet habitual..pre-commit-config.yaml (optional framework):
repos:
- repo: local
hooks:
- id: goimports
name: goimports
entry: goimports -local example.com/mycorp -w
language: system
types: [go]
- id: go-test-quick
name: go test
entry: go test ./...
language: system
pass_filenames: falsePR template excerpt (.github/pull_request_template.md):
## Go quality checklist
- [ ] `make check` passes locally
- [ ] New code has tests for error paths
- [ ] No `context.Background()` in request handlers
- [ ] HTTP/gRPC clients time out and respect cancellation
- [ ] Migrations or config changes documented in PR bodyContributor flow:
git add internal/api/handler.go
git commit -m "add health handler"
# pre-commit runs goimports, gofmt, go vet on staged .go files, then go test ./...What this demonstrates:
.go files for speed.make check remains the documented full gate before push..git/hooks/pre-commit before creating a commit object.| Tier | Checks | Target duration |
|---|---|---|
| Pre-commit | goimports, gofmt, go vet on staged files | < 15s |
| Pre-push | go test ./..., golangci-lint | < 2m |
| CI | race, govulncheck, integration | minutes |
| Area | Reviewer questions |
|---|---|
| Errors | Wrapped with context? Sentinel errors documented? |
| Concurrency | Mutex/channel ownership clear? Context canceled on exit? |
| HTTP/gRPC | Timeouts, body close, status codes correct? |
| Observability | Logs structured with request ID? Metrics for new paths? |
| Security | Input validated? Secrets not logged? SQL parameterized? |
| Tests | Table-driven cases for errors? Race-prone code under -race in CI? |
.PHONY: check hook-install
hook-install:
ln -sf ../../scripts/pre-commit.sh .git/hooks/pre-commit
check:
golangci-lint run ./...
go test -race ./...Document make hook-install in README after clone.
--no-verify abuse. Fix: Move heavy lint to pre-push or CI only.make hook-install in onboarding doc or use pre-commit pre-commit install.-local than CI - Commit passes hook, fails pipeline. Fix: Single source of truth in scripts/ shared by hook and workflow.go test ./... or go test $(go list ./...) at minimum.stages: [commit] with proper file refresh.| Alternative | Use When | Don't Use When |
|---|---|---|
| CI-only gates | Tiny team, always online | Latency-sensitive monorepos |
| pre-push instead of pre-commit | Format noise annoys during WIP commits | You need to block unformatted history |
| Bot auto-fix PRs | High OSS contributor volume | Strict audit trails on main |
| Reviewdog in CI | Surface lint on diff only | Replacing local fast feedback entirely |
Usually no on every commit - too slow.
Run race in CI and optionally on pre-push for concurrency-heavy changes.
git commit --no-verify for emergencies.
Require incident post-mortem if used on main-bound work.
Yes.
Run from workspace root; go test ./... respects all modules in the work file.
Format on generation, not in every commit hook.
Exclude *.pb.go from staged checks if codegen already formats.
Editor save reduces hook failures.
Hooks still catch contributors using different editors or CLI-only workflows.
Automate objective rules (format, errcheck).
Checklist covers design, operability, and security judgment.
Possible but slow.
Prefer native go toolchain on the host for laptop hooks.
Commit scripts/pre-commit.sh or .pre-commit-config.yaml.
Document install step; do not commit .git/hooks directly.
Spot-check on non-trivial PRs.
Trust CI for authoritative signal; spot-check when touching build tags or go.mod.
Quarterly or when incident retros cite missed review themes.
Fewer, sharper items beat long generic lists.
Stack versions: This page was written for Go 1.26.x (Green Tea GC default, go fix modernizers - verify patch at build), chi (latest - verify at build), gin (latest - verify at build), echo (latest - verify at build), google.golang.org/grpc (latest - verify at build), sigs.k8s.io/controller-runtime (latest - verify at build), kubebuilder (latest - verify at build), tinygo (latest - verify board targets at build), wazero (latest - verify at build), and golangci-lint (latest - verify linter set at build).
Reviewed by Chris St. John·Last updated Jul 16, 2026