commit-msg receives the path of the file holding the proposed message, and may read, rewrite or reject it. Sam encodes the style of Commit Messages:
cat > .git/hooks/commit-msg <<'EOF'
#!/bin/sh
# BookNest's message style: a capitalized subject of at most 72 characters,
# with no final period, then a blank line before any body.
subject=$(head -n 1 "$1")
case "$subject" in fixup!*|squash!*|Merge*|Revert*) exit 0 ;; esac
err() { echo "commit-msg: $1"; echo " subject: $subject"; exit 1; }
[ "${#subject}" -le 72 ] || err "the subject is ${#subject} characters; keep it to 72"
case "$subject" in [[:lower:]]*) err "start the subject with a capital letter" ;; esac
case "$subject" in *.) err "drop the period at the end of the subject" ;; esac
[ -z "$(sed -n 2p "$1")" ] || err "leave line 2 blank"
EOF
chmod +x .git/hooks/commit-msg
git commit --allow-empty -qm "fixed the paging tests."
git commit --allow-empty -qm "Fix the paging tests."Output
commit-msg: start the subject with a capital letter subject: fixed the paging tests. commit-msg: drop the period at the end of the subject subject: Fix the paging tests.
The early exit 0 passes subjects Git 1,932 writes itself: fixup! and squash! (Autosquash and Fixup Commits), merges and reverts. [[:lower:]] replaces [a-z], which follows the locale's collation in some shells and can match capitals. Keep such rules mechanical; only a reviewer can judge whether a message explains why. Conventional Commits covers Conventional Commits, checked by tools such as commitlint 18,754 .