Skip to content

Instantly share code, notes, and snippets.

@allenap
Created May 29, 2020 13:42
Show Gist options
  • Save allenap/8ee8c3b3fc8c60eebb3dc21ab12a31d0 to your computer and use it in GitHub Desktop.
Save allenap/8ee8c3b3fc8c60eebb3dc21ab12a31d0 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
set -euo pipefail
#
# Capture the pre-push context.
#
# From githooks(5):
#
# Information about what is to be pushed is provided on the hook's standard
# input with lines of the form:
#
# <local ref> SP <local sha1> SP <remote ref> SP <remote sha1> LF
#
# For instance, if the command git push origin master:foreign were run the
# hook would receive a line like the following:
#
# refs/heads/master 67890 refs/heads/foreign 12345
#
mapfile -t input
dump-input() {
# Reproduce the input for use with another command.
printf '%s\n' "${input[@]}"
}
#
# Check if pushing to a "protected" branch was intended.
#
check-input-for-protected-branch-name() {
local line remote_ref
for line in "${input[@]}"
do
read -r _ _ remote_ref _ <<< "$line"
check-ref-for-protected-branch-name "$remote_ref" || return $?
done
}
check-ref-for-protected-branch-name() {
local remote_ref="$1" answer
# Prevent accidental pushes to "protected" branches.
if [[ $remote_ref =~ /(master|production|staging) ]]
then
printf "You're about to push to %q.\n" "$remote_ref" >&2
read -p "Is that what you intended? [y|N] " -n 1 -s -r answer >&2 < /dev/tty
echo >&2
if [[ $answer != [yY] ]]
then
return 2 # prevents push.
fi
fi
}
check-input-for-protected-branch-name || exit $?
#
# LFS.
#
if type -P git-lfs &> /dev/null
then
dump-input | git lfs pre-push "$@"
else
echo "This repository is configured for Git LFS but 'git-lfs' was not found on your path." >&2
exit 2 # prevents push.
fi
# End.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment