Skip to content

Testing — Git Hook Collection

Test each hook against valid and invalid inputs before installing.

Test the Installer

cd /tmp/hook_test_repo
bash ~/projects/git-hooks/install.sh
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:

ls -la /tmp/hook_test_repo/.git/hooks/ | grep -v sample
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:

echo "Exit: $?"
Exit: 1

Test commit-msg — Valid Messages

echo "feat: add login" | bash ~/projects/git-hooks/commit-msg /dev/stdin
echo "Exit: $?"
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

implementation | enhancements