Hooks live in .git/hooks, which Git does not version. Point core.hooksPath at a folder in the repo so the whole team runs the same ones:
git config core.hooksPath bin/git-hooks
pre-commit: fix style before it lands#
Run Laravel Pint against the staged PHP files only, so the check stays fast:
#!/bin/sh
files=$(git diff --cached --name-only --diff-filter=ACM -- '*.php')
[ -z "$files" ] && exit 0
echo "$files" | xargs ./vendor/bin/pint
echo "$files" | xargs git add
pre-push: run the tests that matter#
A full suite on every commit is too slow to keep. Run it on push instead, where a failure is still cheap:
#!/bin/sh
php artisan test --stop-on-failure
commit-msg: keep the log readable#
Reject empty subjects and very short ones. Everything stricter tends to get bypassed:
#!/bin/sh
subject=$(head -1 "$1")
if [ ${#subject} -lt 10 ]; then
echo "Commit subject too short - say what changed and why." >&2
exit 1
fi
Keep them honest#
A hook the team bypasses with --no-verify every day is worse than none. Start with these three, keep them under a few seconds, and only add more when a real mistake slips through twice.
Share this post
Keep reading
Git Bisect: Find the Commit That Broke It
The tests passed last week and fail now. Bisect turns 'somewhere in these 40 commits' into six test runs.
The Reflog: Undoing Almost Anything in Git
Reset too far, deleted the wrong branch, botched a rebase? The reflog remembers where HEAD has been, and that is usually enough.
What Not to Commit in a Laravel Project
vendor, .env, caches and build output: the short list of what stays out of the repo, and the .gitignore that keeps it out.