IE, Console.log and Git Hooks

Recently had an odd issue with Internet Explorer. I had some code doing a lot or showing and hiding using jQuery. Code worked fine on Firefox and Chrome and worked fine on my Internet Explorer (version 9).

For others using IE my code was failing.

The difference?

I had the IE Developer Tools open.

The problem? An errant console command. I'm pretty thorough about commenting out console.log() and searching for that I found nothing. But searching for 'console.' turned up an uncommented console.dir() and a console.clear().

Oops.

Turns out IE barfs if there is a console statement but no console is available which is why the code was working for me and failing for everyone else.

I'm familiar with hooks in SVN and Git but have never implemented one before but I thought this would be a good solution for my problem.

Lets scan my code for errant console statements with a pre-commit hook.

Hitting Google I found lots of solutions. Many however wouldn't work on Windows.

After some trial and error I found this one which was a step in the right direction. This ran but balked about the GREP_COLOR.

FILES_PATTERN='\.(js|coffee)(\..+)?$'
FORBIDDEN='console.log'
git diff --cached --name-only | \
grep -E $FILES_PATTERN | \
GREP_COLOR='4;5;37;41' xargs grep --color --with-filename -n $FORBIDDEN && echo 'COMMIT REJECTED Found "$FORBIDDEN" references. Please remove them before commiting' && exit 1

After removing the GREP_COLOR reference it worked on Windows!

FILES_PATTERN='\.(js|coffee)(\..+)?$'
FORBIDDEN='console.log'
git diff --cached --name-only | \
grep -E $FILES_PATTERN | \
xargs grep --color --with-filename -n $FORBIDDEN && echo 'COMMIT REJECTED Found "$FORBIDDEN" references. Please remove them before commiting' && exit 1

But I do have a lot of console.log statements in my code I use frequently for debugging. I didn't want to add and remove them all the time so I wanted to just catch any uncommented console statements.

I also wanted to check for other console statements besides .log().

After some more tinkering I came up with:

#!/bin/sh
echo "Executing post-commit checks..."

FILES_PATTERN='\.(js)(\..+)?$'
FORBIDDEN='console\.[clear|dir|log|info|warn|error]'

git diff --cached --name-only | \
grep -E $FILES_PATTERN | \
xargs grep --with-filename -n $FORBIDDEN | \
grep -v '//' && echo 'COMMIT REJECTED!  Found console. references. Please remove them before committing.' && exit 1

I'm no grep expert but this will now look for all the console. alternatives (clear, dir, log, etc) and the "grep -v '//'" will ignore commented console statements.

One note - this will NOT catch multi-line comments!

To make this work on Windows simply open your projects .git folder and look in the \hooks folder. There is already a pre-commit.sample file.

C:\wwwroot\myproject\.git\hooks\pre-commit.sample

Copy that file, delete the existing script and copy my example code into it. Now save the file as 'pre-commit'. No file extension!

That's it. Now crack open a .js file, add a console.log() statement and try to commit.

You should see:

user@PC:/d/wwwroot/myproject $ git commit -m "Test pre-commit hook"
Executing post-commit checks...
myproject/js/main.js:6:          console.log();
COMMIT REJECTED!  Found console. references. Please remove them before committing.

Update 10/24

I noticed that the script would run but never actually COMMIT your files regardless if there was an error or not.

Doh!

Looking at it again it's obvious I need some kind of if/else in there...

Here is my updated version. Now we check for console. and if it's found we EXIT 1 (fail), if not we EXIT 0 (commit).

#!/bin/sh

# 5:23 PM Friday, October 18, 2013 - Jim Priest
# origin script found here: http://python.dzone.com/articles/tips-using-git-pre-commit-hook
# Modified with console checks and to ignore commented file

echo "Executing post-commit checks..."

FILES_PATTERN='\.(js)(\..+)?$'
FORBIDDEN='console\.[clear|dir|log|info|warn|error]'

if git diff --cached --name-only | \
    grep -E $FILES_PATTERN | \
    xargs grep --with-filename -n $FORBIDDEN | \
    grep -v '//';
then
    echo 'COMMIT REJECTED!  Found console. references. Please remove them before committing.'
    exit 1;
fi
exit 0;