Last active
June 9, 2024 13:02
-
-
Save stefansundin/d465f1e331fc5c632088 to your computer and use it in GitHub Desktop.
Git pre-push hook to prevent force pushing the master/main branch.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# This script will install a Git pre-push hook that prevents force pushing the master/main branch. | |
# There are three variants that I have built: | |
# - pre-push: prevents force-pushing to master/main. | |
# - pre-push-2: prevents force-pushing to master/main depending on the remote (you need to edit the file!). | |
# - pre-push-3: prevents any type of pushing to master/main. | |
# Set the desired version like this before proceeding: | |
# FILE=pre-push | |
# Single repo installation: | |
# curl -fL https://gist.githubusercontent.com/stefansundin/d465f1e331fc5c632088/raw/install-pre-push.sh | sh -s ${FILE:-pre-push} | |
# Uninstall: | |
# rm .git/hooks/pre-push | |
# Global installation instructions: | |
# mkdir $HOME/.githooks | |
# git config --global core.hooksPath $HOME/.githooks | |
# curl -fL -o $HOME/.githooks/pre-push https://gist.githubusercontent.com/stefansundin/d465f1e331fc5c632088/raw/${FILE:-pre-push} | |
# chmod +x $HOME/.githooks/pre-push | |
# Uninstall: | |
# rm $HOME/.githooks/pre-push | |
GIT_DIR=`git rev-parse --git-common-dir 2> /dev/null` | |
echo | |
echo | |
if [ "$GIT_DIR" == "" ]; then | |
echo This does not appear to be a git repo. | |
exit 1 | |
fi | |
if [ -f "$GIT_DIR/hooks/pre-push" ]; then | |
echo There is already a pre-push hook installed. Delete it first. | |
echo | |
echo " rm '$GIT_DIR/hooks/pre-push'" | |
echo | |
exit 2 | |
fi | |
FILE=${1:-pre-push} | |
echo "Downloading $FILE hook from https://gist.github.com/stefansundin/d465f1e331fc5c632088" | |
echo | |
curl -fL -o "$GIT_DIR/hooks/pre-push" "https://gist.githubusercontent.com/stefansundin/d465f1e331fc5c632088/raw/$FILE" | |
if [ ! -f "$GIT_DIR/hooks/pre-push" ]; then | |
echo Error downloading pre-push script! | |
exit 3 | |
fi | |
chmod +x "$GIT_DIR/hooks/pre-push" | |
echo "You're all set!" | |
echo "P.S. There is now a way to install this globally, see the instructions on the gist page." | |
exit 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Prevents force-pushing to master/main. | |
# Install: | |
# cd path/to/git/repo | |
# curl -fL -o .git/hooks/pre-push https://gist.githubusercontent.com/stefansundin/d465f1e331fc5c632088/raw/pre-push | |
# chmod +x .git/hooks/pre-push | |
BRANCH=`git rev-parse --abbrev-ref HEAD` | |
PUSH_COMMAND=`ps -ocommand= -p $PPID` | |
if [[ "$BRANCH" =~ ^(master|main)$ && "$PUSH_COMMAND" =~ force|delete|-f ]]; then | |
echo | |
echo "Prevented force-push to $BRANCH. This is a very dangerous command." | |
echo "If you really want to do this, use --no-verify to bypass this pre-push hook." | |
echo | |
exit 1 | |
fi | |
exit 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Use this file to prevent force pushes only to specific remotes (e.g. work). | |
# You have to customize it below ("workorg/"). | |
# Prevents force-pushing to master. | |
# Install: | |
# cd path/to/git/repo | |
# curl -fL -o .git/hooks/pre-push https://gist.githubusercontent.com/stefansundin/d465f1e331fc5c632088/raw/pre-push-2 | |
# chmod +x .git/hooks/pre-push | |
ORIGIN="$1" | |
REMOTE_URL="$2" | |
BRANCH=`git rev-parse --abbrev-ref HEAD` | |
PUSH_COMMAND=`ps -ocommand= -p $PPID` | |
if [[ "$BRANCH" =~ ^(master|main)$ && "$PUSH_COMMAND" =~ force|delete|-f && "$REMOTE_URL" == *"workorg/"* ]]; then | |
echo | |
echo "Prevented force-push to $BRANCH. This is a very dangerous command." | |
echo "If you really want to do this, use --no-verify to bypass this pre-push hook." | |
echo | |
exit 1 | |
fi | |
exit 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Prevents any type of pushing to master/main. | |
# Install: | |
# cd path/to/git/repo | |
# curl -fL -o .git/hooks/pre-push https://gist.githubusercontent.com/stefansundin/d465f1e331fc5c632088/raw/pre-push | |
# chmod +x .git/hooks/pre-push | |
BRANCH=`git rev-parse --abbrev-ref HEAD` | |
if [[ "$BRANCH" =~ ^(master|main)$ ]]; then | |
echo | |
echo "Prevented push to $BRANCH." | |
echo "If you really want to do this, use --no-verify to bypass this pre-push hook." | |
echo | |
exit 1 | |
fi | |
exit 0 |
@stefansundin I wanted to prevent a push without GitHub. Anyway, thanks!
@bilogic You probably want a pre-receive
hook if you have control over the server. I don't have a script ready for you so you are on your own. 😆
It would really have accelerated things if you posted more information up-front, but I guess we finally arrived at the solution. 😅
Good luck!
Is there a way for this to work with husky
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@bilogic Correct, this hook is all local. GitHub has support for protected branches now, which you can use to prevent pushes to certain branches (they didn't have this feature back when I wrote this). https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/about-protected-branches