Preamble
We all know there are certain things in git
, that you should not do. For example you should never force push to the master branch! (For real, do not do this!)
Force pushing on your own feature branch is fine though. While it depends on your personal style, I do not like to have 100 “wip” commits when developing a bigger feature.
Now imagine this: You want to force push something to your personal feature branch. After you amended a little fix to your last commit (with git commit --amend
) you send the force push to your branch but then you realize… oh… That was not my feature branch I am on. That was master
(release
, main
or any other important branch)!
While it is not that terrible and unfixable, you will spend the next minutes informing your team, that the branch is currently in a “dirty” state and that you need to do some rebasing to fix this.
The Fix
To prevent such accidents I found a neat little helper that doesn’t let you force push to any important branches that you might have. I wanted it to be a global fix, so it automatically works on all your git
projects.
# create a global git-hook dir
mkdir ~/git
mkdir ~/git/hooks
# tell git about your new global hook space
git config --global core.hooksPath ~/git/hooks/
# create an awesome hook - the filename is important here!
touch ~/git/hooks/pre-push
# Make it executable
chmod +x ~/git/hooks/pre-push
Now fill ~/git/hooks/pre-push
with this little script. Use the variable PROTECTED_BRANCHES
to add any other important branch, that you want to protect.
#!/bin/bash
# Prevents force-pushing to master
BRANCH=`git rev-parse --abbrev-ref HEAD`
PUSH_COMMAND=`ps -ocommand= -p $PPID`
PROTECTED_BRANCHES="^(master|release*)"
FORCE_PUSH="force|delete|-f"
if [[ "$BRANCH" =~ $PROTECTED_BRANCHES && "$PUSH_COMMAND" =~ $FORCE_PUSH ]]; then
echo "Prevented force-push to protected branch \"$BRANCH\" by pre-push hook"
exit 1
fi
exit 0
Coloured Bash
Here is another quite helpful thing when dealing with git
directly on your bash, instead if just using a GUI: By putting the following snippet to your .bashrc
-file, you get a nice color scheme with green hostname, blue pathname and yellow git branchname. This should work on all Linux or Unix operating systems.
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
PS1="${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[01;33m\]\$(parse_git_branch)\[\033[00m\]$ "
Test
Instead of pushing to the branch it should display an error message like this:
git push --force
Prevented force-push to protected branch "release" by pre-push hook
error: failed to push some refs to 'git@gitlab.netskin.com:netskin/my-awesome-project.git'
Please remember to not to test this on any important project you are working on. ;)
Some more hints how to deal with the force are linked below. Happy Coding!