From 5df529ab6e5f955d0e0fc9d55fae22055bc3b4ad Mon Sep 17 00:00:00 2001 From: bp99 Date: Tue, 28 Jul 2026 18:49:13 +0200 Subject: [PATCH] feat: add conventional-commits commit-msg hook --- README.md | 32 +++++++++++++++++++ .../conventional-commits-v1.0.0.commit-msg | 29 +++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 README.md create mode 100755 commit-msg/conventional-commits-v1.0.0.commit-msg diff --git a/README.md b/README.md new file mode 100644 index 0000000..598a9d5 --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# Client-Side Git Hooks + +To use one of these hooks, copy them from the respective directory to `.githooks/` in your repository and name according to the parent directory, then execute +```shell +git config core.hooksPath .githooks +``` + +It is recommended to then document when you made the copy so you can later propagate upstream changes, eg: +```shell +#!/bin/sh -euC +# +# Reject commit messages that do not conform to Conventional Commits. +# +# Enforces Conventional Commits v1.0.0 at the syntactic level. +# Also enforces a custom list of types. +# +# Upstream: gitea.bp99.eu/bp99/git-hooks +# Updated: 2026-07-15 + +# [... contents ...] +``` + +## Tricks + +To avoid having to remember the `git` command, add a `Makefile` to your project with a `setup` target: +```makefile +setup: + git config core.hooksPath .githooks + +.PHONY: setup +``` +Do not forget to communicate to contributors that this `setup` target should be executed after cloning the repo. diff --git a/commit-msg/conventional-commits-v1.0.0.commit-msg b/commit-msg/conventional-commits-v1.0.0.commit-msg new file mode 100755 index 0000000..eb0b5bf --- /dev/null +++ b/commit-msg/conventional-commits-v1.0.0.commit-msg @@ -0,0 +1,29 @@ +#!/bin/sh -euC +# +# Reject commit messages that do not conform to Conventional Commits. +# +# Enforces Conventional Commits v1.0.0 at the syntactic level. +# +# Upstream: gitea.bp99.eu/bp99/git-hooks + +subject="$(sed -n 1p "$1")" +second="$(sed -n 2p "$1")" + +fail() { + >&2 cat <[()][!]: + +Bypass with: git commit --no-verify +EOF + exit 1 +} + +# type, optional (scope), optional !, terminal ': ', non-emtpy desc +printf '%s' "$subject" | grep -Eq '^[[:alpha:]]+(\([^()]+\))?!?: .+' \ +|| fail 'subject does not conform to Conventional Commits' + +# Body must begin one blank line after description +[ -z "$second" ] || fail 'Line 2 must be blank'