Files
dotfiles/meta/git/hooks/pre-commit
Julian Prein 8a4029121e hooks:pre-commit: Explicitly propagate pipe error
The `die` in the pipe does not exit the whole script but only the pipe.
This currently works because the pipe is the last thing being executed.
If something would come after the pipe, the hook would happily continue
executing. Properly propagate the exit to prevent this in the future.
2025-09-15 17:34:01 +02:00

66 lines
1.8 KiB
Bash
Executable File

#!/bin/sh
#
# A hook script to verify what is about to be committed.
# Called by "git commit" with no arguments. The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the commit.
#
# To enable this hook, save this file in ".git/hooks/pre-commit".
# Source die()
. "$HOME"/.local/bin/helpers.sh
if git rev-parse --verify HEAD >/dev/null 2>&1; then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=$(git hash-object -t tree /dev/null)
fi
# If you want to allow non-ASCII filenames set this variable to true.
allownonascii=$(git config --type=bool hooks.allownonascii)
# Redirect output to stderr.
exec 1>&2
# Check that all filenames include only ASCII characters.
if [ "$allownonascii" != "true" ]; then
# We exploit the fact that the printable range starts at the space
# character and ends with tilde.
# Note that the use of brackets around a tr range is ok here, (it's
# even required, for portability to Solaris 10's /usr/bin/tr), since
# the square bracket bytes happen to fall in the designated range.
num_nonascii=$(
git diff-index --cached --name-only --diff-filter=A -z $against \
| LC_ALL=C tr -d '[ -~]\0' \
| wc -c
)
if [ $num_nonascii != 0 ]; then
die "Rename files with ASCII characters only, or enable hooks.allownonascii"
fi
fi
# Check for whitespace errors.
if ! git diff-index --check --cached $against --; then
die
fi
# Check that added symlinks are neither absolute nor broken
git diff --staged --name-only --diff-filter=AT $against \
| {
abort=0
while read -r line; do
[ -h "$line" ] || continue
target="$(readlink "$line")"
if [ -z "${target##/*}" ]; then
abort=1
printf "%s\n" "$line: Absolute symlink" >&2
fi
if [ ! -e "$line" ]; then
abort=1
printf "%s\n" "$line: Broken symlink" >&2
fi
done
[ "$abort" -eq 0 ] || die
} || exit