#!/bin/bash # TO "INSTALL" # # Put this file in your ~/.githooks directory (or similar) # Make sure the filename is 'pre-commit' # Then add the following to your ~/.gitconfig, uncommented: # # [core] # hooksPath = ~/.githooks # This hook is called by "git commit" with no arguments. It should # exit with non-zero status after issuing an appropriate message if # it wants to stop the commit. branch="$(git rev-parse --abbrev-ref HEAD)" if [ "$branch" = "master" ]; then # I've assumed that personal repos (where I might care less about PRs and such) will use main instead of master echo "You can't commit directly to master branch" exit 1 fi if test -f "$(git rev-parse --show-toplevel)/.git/MERGE_HEAD"; then echo "Skipping pre-commit check for merge commit" exit 0 fi # Stash any changes not staged for commit STASH_NAME=pre-commit-$(date +%s) git stash save -q --keep-index $STASH_NAME # Returns to original pre-stash state, if necessary pop() { STASH_NUM=$(git stash list | grep $STASH_NAME | sed -re 's/stash@\{(.*)\}.*/\1/') # Only necessary if anything was stashed if [ -n "$STASH_NUM" ]; then git stash pop -q stash@{$STASH_NUM} fi } build() { dir="$(echo $PWD | sed 's@/home/[^/]\+/@~/@')" make test &> /dev/null result="$?" if [[ "$result" == 2 ]]; then echo elif [[ "$result" != 0 ]]; then notify-send "Tests failed during commit in $dir" else notify-send "Tests passed in $dir" fi pop } ~/.githooks/pre-commit-build.sh "$STASH_NAME" # # Redirect output to stderr. # exec 1>&2 # # # If the Makefile does not contain the 'test' command, `make test` will exit with '2' # # This is not considered a test failure! # if ! (make test || test $? = 2); then # cat <<\EOF # Error: `make test` exists in the Makefile, but failed # # If you know what you are doing you can skip this check using: # # git commit --no-verify # EOF # pop # exit 1 # fi # # pop