Testing — Git Hook Collection¶
Test each hook against valid and invalid inputs before installing.
Test the Installer¶
Installing hooks from /home/user/projects/git-hooks → /tmp/hook_test_repo/.git/hooks
OK pre-commit → /tmp/hook_test_repo/.git/hooks/pre-commit
OK commit-msg → /tmp/hook_test_repo/.git/hooks/commit-msg
OK pre-push → /tmp/hook_test_repo/.git/hooks/pre-push
Done. Run 'git log --oneline -1' to verify hooks are active.
Verify symlinks:
lrwxrwxrwx 1 user user ... pre-commit -> /home/user/projects/git-hooks/pre-commit
lrwxrwxrwx 1 user user ... commit-msg -> /home/user/projects/git-hooks/commit-msg
lrwxrwxrwx 1 user user ... pre-push -> /home/user/projects/git-hooks/pre-push
Test pre-commit — Valid Script¶
cd /tmp/hook_test_repo
cat > good_script.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
echo "Hello, world!"
EOF
git add good_script.sh
git commit -m "feat: add hello world script"
[pre-commit] Running ShellCheck...
[pre-commit] OK: good_script.sh
[pre-commit] All checks passed.
[main (root-commit) abc1234] feat: add hello world script
Test pre-commit — Bad Script¶
cat > bad_script.sh << 'EOF'
#!/bin/bash
# Missing quotes — ShellCheck will flag this
for f in $(ls *.txt); do
echo $f
done
EOF
git add bad_script.sh
git commit -m "feat: add bad script"
[pre-commit] Running ShellCheck...
In bad_script.sh line 3:
for f in $(ls *.txt); do
^---------^ SC2045: Iterating over ls output is fragile. Use globs.
...
[pre-commit] FAIL: bad_script.sh
[pre-commit] 1 file(s) failed ShellCheck. Fix errors before committing.
[pre-commit] Commit rejected. Fix the above issues and try again.
Exit code should be 1:
Exit: 1
Test commit-msg — Valid Messages¶
Exit: 0
echo "fix(auth): handle null token" | bash ~/projects/git-hooks/commit-msg /dev/stdin
echo "Exit: $?"
Exit: 0
Test commit-msg — Invalid Messages¶
echo "Fixed some stuff" > /tmp/bad_msg
bash ~/projects/git-hooks/commit-msg /tmp/bad_msg
echo "Exit: $?"
[commit-msg] Invalid commit message format.
Got: "Fixed some stuff"
Expected: <type>: <subject> (max 72 chars)
...
Exit: 1
echo "feat:no space after colon" > /tmp/bad_msg2
bash ~/projects/git-hooks/commit-msg /tmp/bad_msg2
echo "Exit: $?"
Exit: 1
Test commit-msg — Merge Commits Pass Through¶
echo "Merge branch 'feature/login' into main" > /tmp/merge_msg
bash ~/projects/git-hooks/commit-msg /tmp/merge_msg
echo "Exit: $?"
Exit: 0
Test pre-push — Normal Push Passes¶
# Simulate a fast-forward push (remote_sha is ancestor of local_sha)
echo "refs/heads/main abc123 refs/heads/main def456" |
bash ~/projects/git-hooks/pre-push origin https://github.com/user/repo.git
echo "Exit: $?"
Exit: 0
Test Trailing Whitespace Detection¶
printf "clean line\ndirty line \n" > whitespace_test.txt
git add whitespace_test.txt
git commit -m "test: check whitespace"
[pre-commit] Trailing whitespace detected:
whitespace_test.txt:2: trailing whitespace.
[pre-commit] Commit rejected. Fix the above issues and try again.
Checklist¶
□ install.sh creates symlinks in .git/hooks/
□ pre-commit blocks commits with ShellCheck failures
□ pre-commit blocks commits with trailing whitespace
□ pre-commit passes when no .sh files are staged
□ commit-msg accepts "feat: valid message"
□ commit-msg rejects messages without type prefix
□ commit-msg passes merge commits unchanged
□ pre-push blocks non-fast-forward push to main
□ shellcheck pre-commit commit-msg pre-push returns 0 warnings