Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Git pre-commit hook that detects if the developer forget to remove all the javascript console.log before commit.
#!/bin/sh
# Redirect output to stderr.
exec 1>&2
# enable user input
exec < /dev/tty
consoleregexp='console.log'
# CHECK
if test $(git diff --cached | grep $consoleregexp | wc -l) != 0
then
exec git diff --cached | grep -ne $consoleregexp
read -p "There are some occurrences of console.log at your modification. Are you sure want to continue? (y/n)" yn
echo $yn | grep ^[Yy]$
if [ $? -eq 0 ]
then
exit 0; #THE USER WANTS TO CONTINUE
else
exit 1; # THE USER DONT WANT TO CONTINUE SO ROLLBACK
fi
fi
@guilherme
Copy link
Author

guilherme commented Mar 17, 2014

To install: simply download and paste into your .git/hooks/pre-commit file

@lfilho
Copy link

lfilho commented Mar 17, 2014

👍

@nicolaslazartekaqui
Copy link

nicolaslazartekaqui commented Mar 18, 2014

👍

@cansadadeserfeliz
Copy link

cansadadeserfeliz commented Jan 6, 2015

👍 Thank you for sharing it!

You have a typo in the word ocurrences.

@TSMMark
Copy link

TSMMark commented Jul 29, 2015

In case it trips anyone else up, this also catches removal of console.log lines too (:

@guilherme
Copy link
Author

guilherme commented Nov 5, 2015

@mkjasinski
Copy link

mkjasinski commented Mar 17, 2016

👍

@danjohnson95
Copy link

danjohnson95 commented May 25, 2016

👍

@saltcod
Copy link

saltcod commented Jun 20, 2016

Hi!

Any idea if I can make this global somehow?

@brugnara
Copy link

brugnara commented Jul 1, 2016

Hi, thanks for sharing. I think this needs an adjustment. If you are removing the console.log, you can not commit!!
I have done a similar thing. Check my regexp, it ensures the line is starting with a plus that indicates you have added a "console.log" and so when removing, git let you commit.

Hope this helps:

regexp='^\+.*console\.log('

@cyphar
Copy link

cyphar commented Aug 6, 2018

I would recommend using git diff -U0 to make sure that no lines of context are matched (so that only changes made will trigger the failure). This (combined with @brughara's proposal of only matching additions and not deletions) would result in much fewer false-positives.

@justforuse
Copy link

justforuse commented Aug 9, 2018

@brugnara Another problem, If you add // console.log(...),it is invalid, but comment shouldn't be denied,I'm poor at regexp, look forward your help

@SimplyComplexable
Copy link

SimplyComplexable commented Aug 24, 2018

@justforuse here is a regex to accomplish what you're looking for: ^\+((?!\/\/).)*console\.log\(

@jschuman
Copy link

jschuman commented Sep 7, 2018

Weird; I had something similar to this working a few months ago but then revisiting I am now getting an error message:
test: !=: unary operator expected

Here's the relevant part of my script:

idchangeregexp='\sid:\s"'
# CHECK
if test $(git diff --cached | grep $idchangeregexp | wc -l) != 0

Any ideas?

@HammzaHM
Copy link

HammzaHM commented May 14, 2020

Thanks a lot Bro

@wcarss
Copy link

wcarss commented Jul 7, 2020

modified the script to the below to use egrep (grep wouldn't work on osx mojave for me, complained of unbalanced parentheses), and to include the filenames in the output:

#!/bin/sh

# sourced from https://gist.github.com/guilherme/9604324 on 2020-07-07

# Redirect output to stderr.
exec 1>&2
# enable user input
exec < /dev/tty

# original: consoleregexp='console.log'
# search for 'console.log(' in added files
consoleregexp='^\+.*console\.log\('

if test `git diff --cached | egrep $consoleregexp | wc -l` != 0
then
  exec git diff --cached | egrep "($consoleregexp|\+{3})"

  # todo note: read -p will break in zsh I think
  read -p "There are some console.log calls in the diff. Do you want to continue? (y/n)" yn
  echo $yn | grep ^[Yy]$
  if [ $? -eq 0 ]
  then
    exit 0; #THE USER WANTS TO CONTINUE
  else
    exit 1; # THE USER DONT WANT TO CONTINUE SO ROLLBACK
  fi
fi

this outputs a result like this:

11:36:29 wcarss@host:~/code (some-branch +)$ git ci
+++ b/onefile
+      console.log("hello");
+++ b/src/SomeDirectory/index.js
+      console.log('test');
There are some console.log calls in the diff. Do you want to continue? (y/n)

@AaronDovTurkel
Copy link

AaronDovTurkel commented Aug 14, 2020

Hi, thanks for sharing. I think this needs an adjustment. If you are removing the console.log, you can not commit!!
I have done a similar thing. Check my regexp, it ensures the line is starting with a plus that indicates you have added a "console.log" and so when removing, git let you commit.

Hope this helps:

regexp='^\+.*console\.log('

Worked this out...

consoleregexp='^[^-]**console.log'

Also this prints out the file names before the console logs...

#!/bin/sh

# Redirect output to stderr.
exec 1>&2
# enable user input
exec < /dev/tty

consoleregexp='^[^-]**console.log'
filenamewithconsole='\(^[^-]**console.log(\|^+++\)'
# CHECK
if test $(git diff --cached | grep $consoleregexp | wc -l) != 0
then 
  exec git diff --cached | grep -ne $filenamewithconsole | grep -B 1 $consoleregexp
  read -p "There are some occurrences of console.log at your modification. Are you sure want to continue? (y/n) " yn
  echo $yn | grep ^[Yy]$
  if [ $? -eq 0 ] 
  then
    exit 0; #THE USER WANTS TO CONTINUE
  else
    exit 1; # THE USER DONT WANT TO CONTINUE SO ROLLBACK
  fi
fi

@emafriedrich
Copy link

emafriedrich commented Dec 18, 2020

Hi, thanks for sharing. I think this needs an adjustment. If you are removing the console.log, you can not commit!!
I have done a similar thing. Check my regexp, it ensures the line is starting with a plus that indicates you have added a "console.log" and so when removing, git let you commit.

Hope this helps:

regexp='^\+.*console\.log('

thanks!!

@TimCreasman
Copy link

TimCreasman commented May 10, 2021

The above script did not quite work for me. I kept getting grep: repetition-operator operand invalid errors.

Here is my tweaked code that I got working:

#!/bin/bash

# Redirect output to stderr.
exec 1>&2
# enable user input
exec < /dev/tty

consoleRegexp='^[^-].*console.log'
filenameRegexp='^[^-].*console.log(\|^+++'

if test "$(git diff --cached | grep -c "$consoleRegexp")" != 0
then
  exec git diff --cached | grep -ne "$filenameRegexp" | grep -B 1 "$consoleRegexp"
  read -rp "There are some occurrences of console.log at your modification. Are you sure want to continue? (y/n) " yn
  if echo "$yn" | grep "^[Yy]$"
  then
    exit 0; #THE USER WANTS TO CONTINUE
  else
    exit 1; # THE USER DONT WANT TO CONTINUE SO ROLLBACK
  fi
fi

Hope this helps someone!

@TheophileMot
Copy link

TheophileMot commented Feb 16, 2022

@TimCreasman Thanks, that's helpful. You can simplify a bit: .* means "any number of characters", so it is redundant to have .*.*. Also, the outer parentheses in filenameRegexp aren't being used, so they can be removed. Thus:

consoleRegexp='^[^-].*console.log'
filenameRegexp='^[^-].*console.log(\|^+++'

@TimCreasman
Copy link

TimCreasman commented Feb 16, 2022

@TheophileMot Thanks for the input! I updated the code with your changes 👍

@TheophileMot
Copy link

TheophileMot commented Feb 17, 2022

@TimCreasman Glad to help! I worked on this myself yesterday; it's starting to get away from the original topic, but other people might find this useful. I wanted to check for a few things (e.g., warn when committing directly to main), so I wrapped the console.log check in a function called no_console, and made another function called check_branch to see whether the current branch is master or main. Each of these calls another function, confirm, when there is a potential problem.

Another small fix: after the "y/n" prompt, I didn't like the duplication of the user input, so instead of the line if echo "$yn" | grep "^[Yy]$", which is a bit hacky, it now just checks the variable directly with if test "$yn" == "y" || test "$yn" == "Y".

I also added some fancy colours.

#!/bin/bash

# Redirect output to stderr.
exec 1>&2
# enable user input
exec < /dev/tty

LRED='\033[1;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # NO COLOUR

confirm () {  
  printf "${YELLOW}"
  read -rp "Continue with commit? (y/n) " yn
  printf "${NC}"
  if test "$yn" == "y" || test "$yn" == "Y"
  then
    printf "\n" # CONTINUE
  else    
    exit 1
  fi
}

check_branch () {
  if test "$(git branch --show-current)" == "master" || test "$(git branch --show-current)" == "main"
  then
    printf "You are on ${LRED}$(git branch --show-current)${NC}.\n"
    confirm
  fi
}

no_console () {
  consoleRegexp='^[^-].*console.log'
  filenameRegexp='^[^-].*console.log(\|^+++'

  if test "$(git diff --cached | grep -c "$consoleRegexp")" != 0
  then
    git diff --cached | grep -ne "$filenameRegexp" | grep -B1 "$consoleRegexp"
    printf "\nSome files include ${LRED}console.log${NC}.\n"
    confirm
  fi
}

### RUN THROUGH CHECKS AND STOP IF THERE IS A PROBLEM
check_branch
no_console

printf "${GREEN}Proceeding with commit...${NC}\n"

This gives a little framework that makes it easier to add further pre-commit checks.


Exercise for the reader: on success, the code as written now displays a "Proceeding with commit" message even when there was no problem. Some people might find this a nuisance. Add a variable to flag whenever the user decides to proceed despite a problem (it can go in the confirm function), and display the "Proceeding" message only when this flag is true.

@Kasik-D
Copy link

Kasik-D commented May 31, 2022

Hello, you are very smart people. Can you help how i add test npm run lint -s && run before this comment. If this command throw error don`t go check console log

@TheophileMot
Copy link

TheophileMot commented May 31, 2022

@Kasik-D Sure. A couple of helpful things to know: $? gives the exit code of whatever command was previously run (the standard is 0 for success, 1 or another number otherwise); also, there are ways to compare numbers in a script, like [[ $x -ne $y ]]. Here -ne stands for "Not Equal to".

So try this:

run_linter () {
  npm lint -s     # or npx eslint *.js, or whatever your lint command is
  if [[ $? -ne 0 ]]
  then
    printf "Oh no\n"
    exit 1
  fi
}

# ...

run_linter
no_console
whatever_other_stuff

@Kasik-D
Copy link

Kasik-D commented Jun 1, 2022

@TheophileMot Thank you, one more qustions what is this programming language ? Where i see instruction of this

@TheophileMot
Copy link

TheophileMot commented Jun 1, 2022

@Kasik-D You're welcome. This language is Bash shell scripting. Bash (or a similar shell, like zsh) is what the terminal runs on MacOS or Linux machines. On Windows, you would have to download it. Learning Bash is a life-long journey, but there are many excellent resources. This looks like a good place to start: https://linuxconfig.org/bash-scripting-tutorial-for-beginners. Have fun!

@Kasik-D
Copy link

Kasik-D commented Jun 1, 2022

@TheophileMot Thanks again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment