#!/usr/bin/env bash # # Pre-commit hook that runs CI-equivalent checks locally. # Classifies staged files by type and only runs relevant make # targets. Falls back to the full `make pre-commit` when the # Makefile changed or CODER_HOOK_RUN_ALL=1 is set. # # Installation (worktree-compatible): # # git config core.hooksPath scripts/githooks # # Bypass: git commit --no-verify set -euo pipefail cd "$(git rev-parse --show-toplevel)" # Unset all repo-local Git env vars, not just GIT_DIR. In linked # worktrees the hook inherits variables like GIT_COMMON_DIR and # GIT_INDEX_FILE that confuse child processes (notably Go's VCS # stamping, which shells out to git and gets exit status 128). # Process substitution (not a pipe) so unset runs in the current shell. while IFS= read -r var; do unset "$var" done < <(git rev-parse --local-env-vars) # In linked worktrees, set worktree-scoped hooksPath to override shared config. if [[ "$(git rev-parse --git-dir)" != "$(git rev-parse --git-common-dir)" ]]; then git config --worktree core.hooksPath scripts/githooks fi if [[ ${CODER_HOOK_RUN_ALL:-} == 1 ]]; then exec make pre-commit fi staged=$(git diff --cached --name-only --diff-filter=d) if [[ -z $staged ]]; then echo "pre-commit: no staged changes, skipping" exit 0 fi # If Go, TS, or build-system files changed, run the full # pre-commit. Otherwise run the lightweight target that # covers everything except gen, Go/TS fmt+lint, and binary build. if echo "$staged" | grep -qE '\.(go|ts|tsx|sql|proto)$|^go\.(mod|sum)$|^site/|^Makefile$'; then exec make pre-commit fi exec make pre-commit-light