diff --git a/.githooks/commit-msg b/.githooks/commit-msg new file mode 100755 index 0000000..b69caf1 --- /dev/null +++ b/.githooks/commit-msg @@ -0,0 +1,30 @@ +#!/bin/sh +# Every commit names the Vikunja task it belongs to. +# +# router: narrow the single-token rule (V-359) +# +# V- and not #, because Gitea autolinks #359 to a Gitea issue, which is a +# different tracker and a wrong link. +# +# Exempt: merges, reverts, fixup/squash, and the initial commit. + +msg_file=$1 +subject=$(sed -n '1p' "$msg_file") + +case "$subject" in + Merge\ *|Revert\ *|fixup!\ *|squash!\ *|amend!\ *) exit 0 ;; +esac + +if [ -f "$(git rev-parse --git-dir)/MERGE_HEAD" ]; then + exit 0 +fi + +if printf '%s' "$subject" | grep -qE '\(V-[0-9]+\)$'; then + exit 0 +fi + +echo "commit-msg: subject must end with a Vikunja task ref." >&2 +echo " got: $subject" >&2 +echo " want: router: narrow the single-token rule (V-359)" >&2 +echo " No task yet? Create one. Work without a task is work nobody can resume." >&2 +exit 1 diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 0000000..73756df --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,30 @@ +#!/bin/sh +# Two guards, both bypassable with --no-verify when you mean it. +# 1. master is not a working branch. +# 2. a code commit stays under 300 changed lines. +# Markdown is exempt from the size cap on purpose: docs land as one batch. + +branch=$(git symbolic-ref --short HEAD 2>/dev/null) + +case "$branch" in + master|main) + echo "pre-commit: refusing to commit on $branch." >&2 + echo " task start # branch off origin/master, write TASK.md" >&2 + exit 1 + ;; +esac + +# Added + deleted lines across staged files that are not markdown. +# numstat prints "-\t-\t" for binaries; those count 0 and that is fine, +# a binary blob is not the kind of diff this cap exists to stop. +loc=$(git diff --cached --numstat -- . ':(exclude)*.md' | + awk '$1 ~ /^[0-9]+$/ { a += $1 } $2 ~ /^[0-9]+$/ { d += $2 } END { print a + d + 0 }') + +if [ "$loc" -gt 300 ]; then + echo "pre-commit: $loc changed lines in non-markdown files, cap is 300." >&2 + echo " Split it. Each commit should be one reviewable idea." >&2 + echo " git reset to unstage, or --no-verify if this genuinely cannot split." >&2 + exit 1 +fi + +exit 0