M0AGX / LB9MG

Amateur radio and embedded systems

Git - confirmation before commit

I use Git for version control of all my projects. Every repository of course has many branches that I try to systematize like: stable, devel, experimental, per-feature etc. Many times I have run into the problem of committing my changes to the branch I did not intended to. Git shows you the branch and changed files when entering the commit message but when you do that 50 times a day you are doomed to loose focus (and commit your experimental stuff into a stable branch :) ).

My solution to this problem is a simple pre-commit hook that reads the name of the branch and prompts for confirmation, if the name of the branch is on a watchlist.

Git hooks are scripts that reside in .git/hooks directory of your local repository. Their names corresponds to the events that call them. In this case the best one to use is pre-commit, which means that the script will be executed before you can type your commit message.

This confirmation script has to be placed in .git/hooks/pre-commit within your repository:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/bin/bash
#This hooks prevents unintentional committing to a branch.
#Customize PATTERN to suit your needs.

PATTERN="stable"
BRANCH=`git rev-parse --abbrev-ref HEAD`

if [[ $BRANCH = *$PATTERN* ]]; then
echo "----------------------------------------------------------------"
echo "WARNING: You are committing to stable branch:" $BRANCH
echo "----------------------------------------------------------------"
else
    exit 0
fi

while true; do
    read -p "Do you really want to commit? y/n " yn < /dev/tty
    case $yn in
        [Yy]* ) exit 0; break;;
        [Nn]* ) exit 1;;
        * ) echo "Please answer y or n.";;
    esac
done

exit 1

and made executable (chmod +x pre-commit).

Whenever the branch name contains the word "stable" the script will prompt for confirmation (and allow git to make the commit or not). It is transparent to other branch names (nothing happens). The name to watch for is the PATTERN variable. This script can be easily customized to look for multiple branch name patterns.

The only non-obvious trick is redirection of /dev/tty to the read command. It is needed, because the shell by defaults reads standard input. In this case Git sends something to standard input of the hook that would be mistaken for normal keystrokes.