Files
dotfiles/meta/git/hooks/commit-msg
Julian Prein 7126a40c71 meta:hooks:commit-msg: Allow {fixup,squash} prefix
Allow the "fixup! " and "squash! " prefix' created by the
`--fixup`/`--squash` flags to `git-commit`
2022-06-23 23:58:33 +02:00

56 lines
1.6 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# A hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file that has the
# commit message.
# The hook should exit with non-zero status after issuing an appropriate message
# if it wants to stop the commit.
# The hook is allowed to edit the commit message file.
#
# To enable this hook, save this file in ".git/hooks/commit-msg".
die() {
printf "$1" >&2
exit ${2:-1}
}
subject="$(head -1 "$1")"
# Ignore "fixup! " and "squash! " prefix' added by `git-commit`
subject="${subject#fixup! }"
subject="${subject#squash! }"
# Because of potential long lines in the changes (when using verbose commit) or
# comments (for example when rebasing), everything until the first comment is
# interpreted as body.
body="$(tail +2 "$1" | sed -n '/^#/q;p')"
[[ ${#subject} -le 50 ]] || die "Subject too long. (<= 50)\n"
# The subject line has to match "${pats[@]}", but to be more verbose different
# error messages are printed for the different 'levels' of the pattern.
declare -a pats msg
pats=(
"^([-_,*(){}./a-zA-Z0-9]+:)+ "
"[A-Z]"
".*[^.]$"
)
msg=(
"Specify which program was modified. (e.g. \"zsh:p10k: <subject>\")\n"
"Start subject with a capital letter.\n"
"Remove punctuation mark from end.\n"
)
[[ ${#msg[@]} -ge ${#pats[@]} ]] || die "Something went wrong internally.\n"
for ((i = 0; i < ${#pats[@]}; i++)); do
if ! grep -qE "$(printf "%s" "${pats[@]:0:$i+1}")" <<<"$subject"; then
die "${msg[$i]}"
fi
done
BKP_IFS="$IFS"
IFS='
'
for line in $body; do
[[ ${#line} -le 72 ]] || die "Body lines too long. (<= 72)\n"
done
IFS="$BKP_IFS"