-
Star
(102)
You must be signed in to star a gist -
Fork
(34)
You must be signed in to fork a gist
-
-
Save stefansundin/9059706 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# This gist contains pre-commit hooks to prevent you from commiting bad code or to the wrong branch. | |
# There are six variants that I have built: | |
# - pre-commit: stops commits to master/main/develop branches. | |
# - pre-commit-2: also includes a core.whitespace check. | |
# - pre-commit-3: the core.whitespace check and an EOF-newline-check. | |
# - pre-commit-4: only the core.whitespace check. | |
# - pre-commit-5: elixir formatting check. | |
# - pre-commit-6: prettier formatting check. | |
# Set the desired version like this before proceeding: | |
# FILE=pre-commit | |
# Install in current Git repo only: | |
# curl -fL https://gist.githubusercontent.com/stefansundin/9059706/raw/install-pre-commit.sh | sh -s ${FILE:-pre-commit} | |
# Uninstall: | |
# rm .git/hooks/pre-commit | |
# Global installation instructions: (requires git 2.9 or later) | |
# NOTE: if you configure core.hooksPath, then git will only run the hooks from that directory (and will ignore repo-specific hooks in .git/hooks/). | |
# mkdir $HOME/.githooks | |
# git config --global core.hooksPath $HOME/.githooks | |
# curl -fL -o $HOME/.githooks/pre-commit https://gist.githubusercontent.com/stefansundin/9059706/raw/${FILE:-pre-commit} | |
# chmod +x $HOME/.githooks/pre-commit | |
# Uninstall: | |
# rm $HOME/.githooks/pre-commit | |
GIT_DIR=`git rev-parse --git-common-dir 2> /dev/null` | |
>&2 echo | |
>&2 echo | |
if [ "$GIT_DIR" == "" ]; then | |
>&2 echo "This does not appear to be a git repo." | |
exit 1 | |
fi | |
if [ -f "$GIT_DIR/hooks/pre-commit" ]; then | |
>&2 echo "There is already a pre-commit hook installed. Delete it first." | |
>&2 echo | |
>&2 echo " rm '$GIT_DIR/hooks/pre-commit'" | |
>&2 echo | |
exit 2 | |
fi | |
FILE=${1:-pre-commit} | |
>&2 echo "Downloading $FILE hook from https://gist.github.com/stefansundin/9059706" | |
>&2 echo | |
curl -fL -o "$GIT_DIR/hooks/pre-commit" "https://gist.githubusercontent.com/stefansundin/9059706/raw/$FILE" | |
if [ ! -f "$GIT_DIR/hooks/pre-commit" ]; then | |
>&2 echo "Error downloading pre-commit script!" | |
exit 3 | |
fi | |
chmod +x "$GIT_DIR/hooks/pre-commit" | |
>&2 echo | |
>&2 echo "You're all set!" | |
>&2 echo "P.S. There is now a way to install this globally, see the instructions on the gist page." | |
exit 0 |
#!/bin/bash | |
# Stops accidental commits to master/main/develop. https://gist.github.com/stefansundin/9059706 | |
# Install: | |
# cd path/to/git/repo | |
# curl -fL -o .git/hooks/pre-commit https://gist.githubusercontent.com/stefansundin/9059706/raw/pre-commit | |
# chmod +x .git/hooks/pre-commit | |
BRANCH=`git rev-parse --abbrev-ref HEAD` | |
if [[ "$BRANCH" =~ ^(master|main|develop)$ ]]; then | |
>&2 echo "You are on branch $BRANCH. Are you sure you want to commit to this branch?" | |
>&2 echo "If so, commit with -n to bypass this pre-commit hook." | |
exit 1 | |
fi | |
exit 0 |
#!/bin/bash | |
# Stops accidental commits to master/main/develop. https://gist.github.com/stefansundin/9059706 | |
# Install: | |
# cd path/to/git/repo | |
# curl -fL -o .git/hooks/pre-commit https://gist.githubusercontent.com/stefansundin/9059706/raw/pre-commit-2 | |
# chmod +x .git/hooks/pre-commit | |
BRANCH=`git rev-parse --abbrev-ref HEAD` | |
if [[ "$BRANCH" =~ ^(master|main|develop)$ ]]; then | |
>&2 echo "You are on branch $BRANCH. Are you sure you want to commit to this branch?" | |
>&2 echo "If so, commit with -n to bypass this pre-commit hook." | |
exit 1 | |
fi | |
if [ "`git diff --check --cached | wc -c`" -gt 0 ]; then | |
>&2 echo "Your spaces don't agree with your core.whitespace rules." | |
>&2 echo 'Please run `git diff --check HEAD` to see your errors.' | |
>&2 echo "You can commit with -n to bypass this pre-commit hook." | |
exit 2 | |
fi | |
exit 0 |
#!/bin/bash | |
# Stops accidental commits to master/main/develop. https://gist.github.com/stefansundin/9059706 | |
# Install: | |
# cd path/to/git/repo | |
# curl -fL -o .git/hooks/pre-commit https://gist.githubusercontent.com/stefansundin/9059706/raw/pre-commit-3 | |
# chmod +x .git/hooks/pre-commit | |
BRANCH=`git rev-parse --abbrev-ref HEAD` | |
if [[ "$BRANCH" =~ ^(master|main|develop)$ ]]; then | |
>&2 echo "You are on branch $BRANCH. Are you sure you want to commit to this branch?" | |
>&2 echo "If so, commit with -n to bypass this pre-commit hook." | |
exit 1 | |
fi | |
if [ "`git diff --check --cached | wc -c`" -gt 0 ]; then | |
>&2 echo "Your spaces don't agree with your core.whitespace rules." | |
>&2 echo 'Please run `git diff --check HEAD` to see your errors.' | |
>&2 echo "You can commit with -n to bypass this pre-commit hook." | |
exit 2 | |
fi | |
NOEOF=() | |
FILES=`git status --porcelain | grep "^M" | cut -b4-` | |
while read -r f; do | |
if [ "`tail -c 1 $f`" != "" ]; then | |
NOEOF+=("$f") | |
fi | |
done <<< "$FILES" | |
if [ ${#NOEOF[@]} -gt 0 ]; then | |
>&2 echo "No newlines at the end of these files:" | |
for f in "${NOEOF[@]}"; do | |
>&2 echo " $f" | |
done | |
>&2 echo | |
>&2 echo "To check your whole repository, run this:" | |
>&2 echo | |
>&2 echo ' git ls-tree -r -z --name-only HEAD | xargs -0 file | grep text | cut -d: -f1 | xargs -I {} bash -c '\''if [ -n "`tail -c 1 "{}"`" ]; then echo {}; fi'\''' | |
>&2 echo | |
>&2 echo "You can commit with -n to bypass this pre-commit hook." | |
exit 3 | |
fi | |
exit 0 |
#!/bin/bash | |
# Checks yo whitespace on commit. https://gist.github.com/stefansundin/9059706 | |
# Install: | |
# cd path/to/git/repo | |
# curl -fL -o .git/hooks/pre-commit https://gist.githubusercontent.com/stefansundin/9059706/raw/pre-commit-4 | |
# chmod +x .git/hooks/pre-commit | |
if [ "`git diff --check --cached | wc -c`" -gt 0 ]; then | |
>&2 echo "Your spaces don't agree with your core.whitespace rules." | |
>&2 echo 'Please run `git diff --check HEAD` to see your errors.' | |
>&2 echo "You can commit with -n to bypass this pre-commit hook." | |
exit 2 | |
fi | |
exit 0 |
#!/bin/bash | |
# Checks elixir formatting on commit. https://gist.github.com/stefansundin/9059706 | |
# Install: | |
# cd path/to/git/repo | |
# curl -fL -o .git/hooks/pre-commit https://gist.githubusercontent.com/stefansundin/9059706/raw/pre-commit-5 | |
# chmod +x .git/hooks/pre-commit | |
if [ "`git diff --check --cached | wc -c`" -gt 0 ]; then | |
>&2 echo "Your spaces don't agree with your core.whitespace rules." | |
>&2 echo 'Please run `git diff --check HEAD` to see your errors.' | |
>&2 echo "You can commit with -n to bypass this pre-commit hook." | |
exit 2 | |
fi | |
mix format --check-formatted || { | |
>&2 echo "You can commit with -n to bypass this pre-commit hook." | |
exit 3 | |
} | |
exit 0 |
#!/bin/bash | |
# Checks prettier formatting on commit. https://gist.github.com/stefansundin/9059706 | |
# Install: | |
# cd path/to/git/repo | |
# curl -fL -o .git/hooks/pre-commit https://gist.githubusercontent.com/stefansundin/9059706/raw/pre-commit-6 | |
# chmod +x .git/hooks/pre-commit | |
if [ "`git diff --check --cached | wc -c`" -gt 0 ]; then | |
>&2 echo "Your spaces don't agree with your core.whitespace rules." | |
>&2 echo 'Please run `git diff --check HEAD` to see your errors.' | |
>&2 echo "You can commit with -n to bypass this pre-commit hook." | |
exit 2 | |
fi | |
# https://prettier.io/docs/en/precommit.html#option-6-shell-script | |
jsfiles=$(git diff --cached --name-only --diff-filter=ACMR "*.js" "*.jsx" "*.ts" "*.tsx" "*.gql" | tr '\n' ' ') | |
[ -z "$jsfiles" ] && exit 0 | |
jsfiles=$(echo "$jsfiles" | xargs ./node_modules/.bin/prettier -l) | |
[ -z "$jsfiles" ] && exit 0 | |
>&2 echo "The following files do not conform to prettier formatting:" | |
>&2 echo "$jsfiles" | |
>&2 echo | |
>&2 echo "See the problem in each file with the following:" | |
echo "$jsfiles" | while read -r file; do | |
>&2 echo "prettier '$file' | diff '$file' -" | |
done | |
>&2 echo | |
>&2 echo "Apply changes with the following:" | |
echo "$jsfiles" | while read -r file; do | |
>&2 echo "prettier --write '$file'" | |
done | |
>&2 echo | |
>&2 echo "Don't forget to run 'git add' afterwards!" | |
>&2 echo "You can commit with -n to bypass this pre-commit hook." | |
exit 3 |
Thank you! Very useful.
Thanks!
Thanks a lot
I just updated the instructions above to include instructions for a global installation using the core.hooksPath
configuration option introduced in Git 2.9. Update to that and you no longer have to install this in every git repository, just do it once.
Thank you for this @stefansundin !
Could you please tell me the license under which your code is available?
Cheers 🍻
@lharzenetter Hmm.. I never thought about putting a license on this. But since you want one, maybe WTFPL will work? I'm a bit excited now because it's my first thing under that license. Let me know if another license would suit you better. Thanks!
For warnings and errors, it would be good to use echo
with >&2
to send the messages to stderr
.
thanks a lot
@felipe1982 Done. 👍
Thanks! This is great 👍