Files
Jon Leopard 60a375960f refactor: improve pre-commit hook to format only staged files
Changes:
- Format only staged PHP files (not all dirty files)
- Auto-stage only the files that were already staged
- Prevents accidentally staging unstaged changes
- Safer for partial staging workflows
- Maintains full automation for normal commits

This aligns with industry best practices from lint-staged
and prevents security risks from staging unintended files.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 22:21:54 -07:00
..

Git Hooks for Cannabrands CRM

Best Practice: Graduated Enforcement

Defense in Depth Strategy:

  1. Pre-commit hook (ENFORCED) - Auto-format code (~1 second)
  2. Pre-push hook (OPTIONAL) - Run tests before push (~30-60 seconds)
  3. CI pipeline (REQUIRED) - Final verification, blocks deployment

Installation

One-time setup (after cloning):

# Configure Git to use .githooks directory
git config core.hooksPath .githooks

# Make hooks executable
chmod +x .githooks/*

Available Hooks

pre-commit - Laravel Pint Auto-formatter ENFORCED

What it does:

  • Runs Laravel Pint on staged PHP files only (not unstaged files)
  • Auto-formats code to match team standards
  • Automatically re-stages the formatted files
  • Fast feedback (runs in seconds)
  • Safe: Won't format or stage files you haven't explicitly added

When it runs:

  • Every time you run git commit
  • Before your commit is created

Bypass if needed:

# Skip hooks (not recommended, CI will still catch it)
git commit --no-verify -m "message"

What it does:

  • Runs your test suite before pushing
  • Catches failing tests before CI runs
  • Saves time by finding issues locally

When it runs:

  • Every time you run git push
  • Before code is sent to remote

Bypass when needed:

# Skip when pushing WIP or non-code changes
git push --no-verify

Why optional?

  • Takes 30-60 seconds (vs formatting's <1 second)
  • Sometimes you want to push WIP to share with team
  • CI will catch it anyway as final gate

Enforcement Levels Explained

Hook Speed Enforcement Can Bypass? Purpose
Pre-commit ~1s Strict Yes (but don't) Code formatting
Pre-push ~30s ⚠️ Suggested Yes (sometimes needed) Run tests
CI Pipeline ~5min 🚫 Required No Final gate

Example Workflows:

Scenario 1: Normal development

1. Make changes → git commit
   → Pre-commit runs Pint → Code formatted ✅
   → Commit created ✅

2. git push
   → Pre-push runs tests → All pass ✅
   → Code pushed to remote ✅

3. CI runs
   → Tests + Build → Everything passes ✅
   → Ready to deploy ✅

Scenario 2: Pushing WIP (work in progress)

1. Make changes → git commit
   → Pre-commit runs Pint → Code formatted ✅

2. git push --no-verify  (skip pre-push tests)
   → Push WIP to remote ✅

3. CI runs
   → Tests fail (expected for WIP) ❌
   → Fix later before merge ✅

Scenario 3: Developer bypasses everything

1. git commit --no-verify  (skip formatting)
   → Unformatted code committed ❌

2. git push --no-verify  (skip tests)
   → Pushed to remote ❌

3. CI runs
   → Code style fails → Build fails 🚫
   → Can't deploy → Must fix ✅

Philosophy: Small Team Balance

"Make the right thing easy, and the wrong thing possible (but audited)."

For our 5-person team:

  • Hooks make it easy to follow standards (automatic formatting)
  • --no-verify makes it possible to bypass (for WIP/emergencies)
  • CI makes bypasses audited (they'll fail the build)

Why this works for small teams:

  • Fast checks are automatic (no thinking)
  • Slow checks are optional (developer discretion)
  • Final gate blocks broken code (can't deploy)
  • High trust, low friction

As team grows (10-20 developers):

  • Consider making tests mandatory (remove --no-verify option)
  • Add code review requirements
  • Tighten enforcement where needed

Current enforcement is "Goldilocks" - not too strict (frustrating), not too lenient (risky), just right for 5 developers who know each other.

Troubleshooting

Hook not running?

# Check if hooks path is configured
git config core.hooksPath

# Should show: .githooks
# If not, run: git config core.hooksPath .githooks

Hook permission denied?

chmod +x .githooks/pre-commit

Want to test hook without committing?

./.githooks/pre-commit