// Git Toolbox
Générateur de hooks Git
Les hooks sont des scripts que Git lance avant un commit ou un push. Choisis les vérifications, récupère les scripts et la façon de les installer.
pre-commit
Avant chaque commit : vérifie les fichiers indexés.
commit-msg
Vérifie le message de commit.
prepare-commit-msg
Prépare le message avant l'ouverture de l'éditeur.
pre-push
Avant chaque push : dernière chance avant le serveur.
Installer
Dans .git/hooks : jamais commité, seulement sur ta machine.
Copie, colle dans un terminal à la racine de ton dépôt, c'est fini :
cat > .git/hooks/pre-commit <<'GITPUSHF_EOF'#!/bin/sh# pre-commit — generated by gitpushf.uk# Skip once: --no-verify (git commit --no-verify, git push --no-verify)# --- No commits directly on mainbranch=$(git symbolic-ref --short HEAD 2>/dev/null)case "$branch" inmain|master)echo "✖ Direct commit on $branch. Create a branch first: git switch -c my-branch"exit 1 ;;esac# --- No forgotten conflict markersif git diff --cached -U0 | grep -qE '^\+(<<<<<<< |=======$|>>>>>>> )'; thenecho "✖ Conflict markers in your staged changes (<<<<<<< / ======= / >>>>>>>)."exit 1fi# --- No secrets or .env filesif git diff --cached --name-only --diff-filter=A | grep -E '(^|/)\.env(\.[^/]*)?$' | grep -vqE '\.(example|sample|template)$'; thenecho "✖ A .env file is staged. Remove it: git restore --staged <file>, then add it to .gitignore."exit 1fiif git diff --cached -U0 | grep -qE '^\+.*(-----BEGIN [A-Z ]*PRIVATE KEY-----|AKIA[0-9A-Z]{16}|sk_live_[0-9A-Za-z]{10,}|gh[pousr]_[0-9A-Za-z]{36}|github_pat_[0-9A-Za-z_]{20,}|glpat-[0-9A-Za-z_-]{20}|xox[abprs]-[0-9A-Za-z-]{10,}|sk-ant-[0-9A-Za-z_-]{20,})'; thenecho "✖ Something that looks like a secret is staged. Check: git diff --cached"exit 1fi# --- No files over 5 MBlimit=5242880git diff --cached --name-only --diff-filter=AM | while IFS= read -r file; dosize=$(git cat-file -s ":$file" 2>/dev/null || echo 0)if [ "$size" -gt "$limit" ]; thenecho "✖ $file is $((size / 1048576)) MB (limit 5 MB). Use Git LFS: git lfs track \"$file\""exit 1fidone || exit 1GITPUSHF_EOFcat > .git/hooks/commit-msg <<'GITPUSHF_EOF'#!/bin/sh# commit-msg — generated by gitpushf.uk# Skip once: --no-verify (git commit --no-verify, git push --no-verify)# $1 = file that holds the commit messagefirst=$(head -n 1 "$1")# --- Conventional Commitscase "$first" inMerge*|Revert*|fixup!*|squash!*|amend!*) ;;*)# An optional "[JIRA-123] " prefix is allowed (added by the ticket hook).if ! printf '%s\n' "$first" | grep -qE '^(\[[A-Z][A-Z0-9]+-[0-9]+\] )?(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([a-z0-9._/-]+\))?!?: .+'; thenecho "✖ Commit message must follow Conventional Commits: type(scope): description"echo " e.g. feat(auth): add Discord login"exit 1fi ;;esacGITPUSHF_EOFcat > .git/hooks/pre-push <<'GITPUSHF_EOF'#!/bin/sh# pre-push — generated by gitpushf.uk# Skip once: --no-verify (git commit --no-verify, git push --no-verify)# Git sends one line per pushed ref on stdin: <local ref> <local sha> <remote ref> <remote sha>refs=$(cat)# --- No direct push to mainprintf '%s\n' "$refs" | while read -r local_ref local_sha remote_ref remote_sha; docase "$remote_ref" inrefs/heads/main|refs/heads/master)echo "✖ Direct push to ${remote_ref#refs/heads/} is blocked. Push a branch and open a pull request."exit 1 ;;esacdone || exit 1# --- No WIP / fixup! commits pushedzero=0000000000000000000000000000000000000000printf '%s\n' "$refs" | while read -r local_ref local_sha remote_ref remote_sha; do[ -z "$local_sha" ] && continue[ "$local_sha" = "$zero" ] && continueif [ "$remote_sha" = "$zero" ]; thensubjects=$(git log --format=%s "$local_sha" --not --remotes)elsesubjects=$(git log --format=%s "$remote_sha..$local_sha")fiif printf '%s\n' "$subjects" | grep -qiE '^(wip|fixup!|squash!)'; thenecho "✖ WIP or fixup! commits in $local_ref. Clean up: git rebase -i --autosquash"exit 1fidone || exit 1GITPUSHF_EOFchmod +x .git/hooks/pre-commit .git/hooks/commit-msg .git/hooks/pre-push
Cette commande crée tous les fichiers de hooks d'un coup. Pour changer une vérification, reviens ici et recolle-la.
Tu préfères créer les fichiers toi-même ? Les voir un par un
# Save each script as .git/hooks/<hook name>, then:$ chmod +x .git/hooks/pre-commit .git/hooks/commit-msg .git/hooks/pre-push
#!/bin/sh# pre-commit — generated by gitpushf.uk# Skip once: --no-verify (git commit --no-verify, git push --no-verify)# --- No commits directly on mainbranch=$(git symbolic-ref --short HEAD 2>/dev/null)case "$branch" inmain|master)echo "✖ Direct commit on $branch. Create a branch first: git switch -c my-branch"exit 1 ;;esac# --- No forgotten conflict markersif git diff --cached -U0 | grep -qE '^\+(<<<<<<< |=======$|>>>>>>> )'; thenecho "✖ Conflict markers in your staged changes (<<<<<<< / ======= / >>>>>>>)."exit 1fi# --- No secrets or .env filesif git diff --cached --name-only --diff-filter=A | grep -E '(^|/)\.env(\.[^/]*)?$' | grep -vqE '\.(example|sample|template)$'; thenecho "✖ A .env file is staged. Remove it: git restore --staged <file>, then add it to .gitignore."exit 1fiif git diff --cached -U0 | grep -qE '^\+.*(-----BEGIN [A-Z ]*PRIVATE KEY-----|AKIA[0-9A-Z]{16}|sk_live_[0-9A-Za-z]{10,}|gh[pousr]_[0-9A-Za-z]{36}|github_pat_[0-9A-Za-z_]{20,}|glpat-[0-9A-Za-z_-]{20}|xox[abprs]-[0-9A-Za-z-]{10,}|sk-ant-[0-9A-Za-z_-]{20,})'; thenecho "✖ Something that looks like a secret is staged. Check: git diff --cached"exit 1fi# --- No files over 5 MBlimit=5242880git diff --cached --name-only --diff-filter=AM | while IFS= read -r file; dosize=$(git cat-file -s ":$file" 2>/dev/null || echo 0)if [ "$size" -gt "$limit" ]; thenecho "✖ $file is $((size / 1048576)) MB (limit 5 MB). Use Git LFS: git lfs track \"$file\""exit 1fidone || exit 1
#!/bin/sh# commit-msg — generated by gitpushf.uk# Skip once: --no-verify (git commit --no-verify, git push --no-verify)# $1 = file that holds the commit messagefirst=$(head -n 1 "$1")# --- Conventional Commitscase "$first" inMerge*|Revert*|fixup!*|squash!*|amend!*) ;;*)# An optional "[JIRA-123] " prefix is allowed (added by the ticket hook).if ! printf '%s\n' "$first" | grep -qE '^(\[[A-Z][A-Z0-9]+-[0-9]+\] )?(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([a-z0-9._/-]+\))?!?: .+'; thenecho "✖ Commit message must follow Conventional Commits: type(scope): description"echo " e.g. feat(auth): add Discord login"exit 1fi ;;esac
#!/bin/sh# pre-push — generated by gitpushf.uk# Skip once: --no-verify (git commit --no-verify, git push --no-verify)# Git sends one line per pushed ref on stdin: <local ref> <local sha> <remote ref> <remote sha>refs=$(cat)# --- No direct push to mainprintf '%s\n' "$refs" | while read -r local_ref local_sha remote_ref remote_sha; docase "$remote_ref" inrefs/heads/main|refs/heads/master)echo "✖ Direct push to ${remote_ref#refs/heads/} is blocked. Push a branch and open a pull request."exit 1 ;;esacdone || exit 1# --- No WIP / fixup! commits pushedzero=0000000000000000000000000000000000000000printf '%s\n' "$refs" | while read -r local_ref local_sha remote_ref remote_sha; do[ -z "$local_sha" ] && continue[ "$local_sha" = "$zero" ] && continueif [ "$remote_sha" = "$zero" ]; thensubjects=$(git log --format=%s "$local_sha" --not --remotes)elsesubjects=$(git log --format=%s "$remote_sha..$local_sha")fiif printf '%s\n' "$subjects" | grep -qiE '^(wip|fixup!|squash!)'; thenecho "✖ WIP or fixup! commits in $local_ref. Clean up: git rebase -i --autosquash"exit 1fidone || exit 1
Besoin de passer une vérification une fois ? git commit --no-verify ou git push --no-verify.
Marche aussi sous Windows : Git for Windows lance ces scripts avec son propre shell.