#!/bin/bash # 安裝 git hooks(pre-commit)以執行 clang-format 與可選的 clang-tidy 提示 set -euo pipefail HOOKS_DIR=".git/hooks" PRE_COMMIT="$HOOKS_DIR/pre-commit" if [ ! -d "$HOOKS_DIR" ]; then echo "This script must be run inside a Git repository." exit 1 fi cat > "$PRE_COMMIT" <<'EOF' #!/bin/bash set -euo pipefail echo "[pre-commit] Checking/formatting C++ sources..." # Collect staged C/C++ files STAGED=$(git diff --cached --name-only --diff-filter=ACMR | grep -E '\.(cpp|cxx|cc|c\+\+|h|hpp|hxx)$' || true) if [ -z "$STAGED" ]; then echo "[pre-commit] No C/C++ files staged." exit 0 fi # 1) clang-format in-place, then re-stage if command -v clang-format >/dev/null 2>&1; then echo "$STAGED" | xargs -r clang-format -i echo "$STAGED" | xargs -r git add else echo "[pre-commit] clang-format not found; skipping formatting." >&2 fi # If formatting changed files, fail once to let user review CHANGES=$(git diff --name-only --diff-filter=ACMR | grep -E '\\.(cpp|cxx|cc|c\\+\\+|h|hpp|hxx)$' || true) if [ -n "$CHANGES" ]; then echo "[pre-commit] Formatting applied to:" echo "$CHANGES" echo "[pre-commit] Please review changes and re-commit." exit 1 fi # 2) Optional clang-tidy advisory (Phase 1: do not block commits) if command -v clang-tidy >/dev/null 2>&1; then if [ -f build/compile_commands.json ]; then echo "[pre-commit] Running clang-tidy (advisory)..." echo "$STAGED" | xargs -r clang-tidy -p build --config-file=.clang-tidy || true else echo "[pre-commit] No build/compile_commands.json; skip clang-tidy. Run CMake with -DCMAKE_EXPORT_COMPILE_COMMANDS=ON." fi fi exit 0 EOF chmod +x "$PRE_COMMIT" echo "Installed pre-commit hook to $PRE_COMMIT"