Tuesday 8 April 2014

pre-commit Hook to Prevent Debug Value / Code From Being Committed

It is not uncommon that sometimes you end up committing a wrong code, probably with debug values and codes that you have put for temporary basis to test out something. I have several times committed a code that had some hardcoded values or debug messages which I put to test my code in different scenarios. It is quite hard to spot this mistake if your "wrong code" is the part of a rare scenario. And when this code goes into the production and the rare time comes, you will see either scared users or screaming users.

To avoid such mistakes, I wrote a small bash script few weeks back to be executed in pre-commit hook of git. This script looks for a particular text ( I call it #DUMMYTEXT) in your code in your staging area and stops you from committing the code if found. Unfortunately, you have to make habit of putting your #DUMMYTEXT every time (or at least once in the file) you are putting dummy values or code.

What is a Git Hook?

Hooks are nothing but a some scripts that are automatically executed for certain events.  To read more about hooks, go to http://git-scm.com/book/en/Customizing-Git-Git-Hooks

In our case, we will be using pre-commit, a client side hook, which is executed just before the code is committed. You can do whatever you want to do and decide if you want to proceed with commit or abort the commit. 

How do I create a hook?

In Git, hooks are per-repo basis. That means, you create separate hooks for each repository. You will find .git ( hidden) directory in root your repository. Inside that directory, you will see a .hooks directory. Usually, it is filled with sample hooks. In our case, we will need to put our script in pre-commit file. You can either create new one or rename pre-commit.sample to pre-commit and put the validation code/script there.

Where is the code?

#PUT YOUR OWN WORD TO LOOK FOR. BUT KEEP IT UNIQUE
debugText='#DUMMYTEXT'

filelist=(`git diff --cached --name-only --diff-filter=ACMR`)

found=0

for FILE in ${filelist[*]}
do
 if git grep --cached -q "$debugText" "$FILE"; then
  
  if [ $found -eq 0 ]; then
   echo "[ERROR] Following file(s) contains $debugText. Please remove debug text and values(if any):"
  fi
  found=1
  echo "$FILE"
  
 fi
  
done

exit $found

How do I work with this?

I recommend making a habit to put debug text every time you are putting dummy texts or values. So that you do not miss any dummy values. 

So if any time, you mistakenly stage a file with dummy text/values and try to commit , this script will stop you from committing the code.

Notes

If you forget to put your debug text, there is no way anyone case save you. ;-)  Feedback/Suggestion is highly appreciated! :-)