Skip to content

Instantly share code, notes, and snippets.

@sir-pinecone
Last active September 21, 2020 04:23
Show Gist options
  • Save sir-pinecone/0ce0eabcfbe14e0ecfc69c5fb816fe7f to your computer and use it in GitHub Desktop.
Save sir-pinecone/0ce0eabcfbe14e0ecfc69c5fb816fe7f to your computer and use it in GitHub Desktop.
Stop a Git commit if a staged file contains the word "nocheckin".
#!/usr/bin/env bash
# Stops the commit if the changes include the word `nocheckin`.
if which tput >/dev/null 2>&1; then
ncolors=$(tput colors)
fi
if [ -t 1 ] && [ -n "$ncolors" ] && [ "$ncolors" -ge 8 ]; then
RED="$(tput setaf 1)"
GREEN="$(tput setaf 2)"
YELLOW="$(tput setaf 3)"
BLUE="$(tput setaf 4)"
MAGENTA="$(tput setaf 5)"
CYAN="$(tput setaf 6)"
BOLD="$(tput bold)"
NORMAL="$(tput sgr0)"
DIM="\e[2m"
else
RED=""
GREEN=""
YELLOW=""
BLUE=""
MAGENTA=""
CYAN=""
BOLD=""
NORMAL=""
fi
printf "${BOLD}${YELLOW}Looking for 'nocheckin'${NORMAL}\n\n"
change_set=$(git status -s | grep "^[MARCD]")
file_types_to_check="\(.cpp\|.c\|.h\|.txt\|.md\|.js\|.cs\|.cshtml\|.config\|.variables\|.gl\|.keymap\|.sound_tweaks\)$"
abort_commit=0
while IFS= read -r line
do
# It's a lot faster to use parameter expansion rather than `cut`.
action="${line::1}" # Action is either one or two characters followed by N spaces, but we can work off the first character.
change="${line:2}" # Skip action and strip all leading spaces.
change="${change#"${change%%[![:space:]]*}"}"
#echo "action: '$action' | change: '$change'"
if [[ $action == "D" ]]; then
continue
elif [[ $action == "R" ]]; then
# Extract the new filename.
change=$(awk -F " -> " '{print $2}' <<< "$change")
fi
# Strip leading and trailing double quotes. This is faster than using sed like so:
# filename=$(sed -e 's/^"//' -e 's/"$//' <<< "$change")
filename="${change%\"}"
filename="${filename#\"}"
file_path="$(pwd)/${filename}"
#echo "file path: $file_path"
look_at_file=$(grep -e "$file_types_to_check" -i <<< "$filename")
if [[ "$look_at_file" != "" ]]; then
index=1
printf "${MAGENTA}==> ${NORMAL}${BOLD}${filename}${NORMAL}\n"
errors=$(grep "nocheckin" "$file_path" >&1)
if [[ "$errors" != "" ]]; then
abort_commit=1
printf "${BOLD}${RED}$errors${NORMAL}\n"
fi
else
printf "${MAGENTA}==> ${NORMAL}${DIM}$filename${NORMAL}\n"
fi
done <<< "$change_set" # Make the loop run in the main shell process so that we can modify the outside variables.
if [[ $abort_commit -eq 1 ]]; then
printf "\n${RED}${BOLD}Aborting!${NORMAL}\n"
exit 1
else
printf "\n${GREEN}${BOLD}All good!${NORMAL}\n"
fi
printf "\n"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment