I am trying to add a git pre-commit hook that will check all changed and new file for TODO:
text.
I tried
#!/bin/sh
. git-sh-setup # for die
git-diff-index -p -M --cached HEAD -- | grep '^+' |
grep TODO: && die Blocking commit because string TODO: detected in patch
:
That i saw in a similar question, but no luck.
This bit loops over the files that are staged, yes, but it then greps the entire file regardless of what portions of it are staged!
git diff --cached --name-only | \ grep -E $FILES_PATTERN | \ echo 'COMMIT REJECTED Found' $i 'references. Please remove them before commiting' && exit 1
That's no good - don't test strings that aren't staged.
This solution tests one or multiple FORBIDDEN strings against only the staged code, not the entire file:
#!/bin/bash
RESTORE='\033[0m'
RED='\033[00;31m'
YELLOW='\033[00;33m'
BLUE='\033[00;34m'
FORBIDDEN=( 'TODO:' 'DO NOT COMMIT' 'console.log' 'die' )
FOUND=''
for j in "${FORBIDDEN[@]}"
do
for i in `git diff --cached --name-only`
do
# the trick is here...use `git show :file` to output what is staged
# test it against each of the FORBIDDEN strings ($j)
if echo `git show :$i` | grep -q "$j"; then
FOUND+="${BLUE}$i ${RED}contains ${RESTORE}\"$j\"${RESTORE}\n"
fi
done
done
# if FOUND is not empty, REJECT the COMMIT
# PRINT the results (colorful-like)
if [[ ! -z $FOUND ]]; then
printf "${YELLOW}COMMIT REJECTED\n"
printf "$FOUND"
exit 1
fi
# nothing found? let the commit happen
exit 0
First, the hook must be in the .git/hook
folder and name pre-commit
(with execution right: chmod +x .git/hooks/pre-commit
)
The OP jesusjjf confirms in the comments that was the issue:
I had copied what was in the
pre-commit.sample
file onto a plain text file, instead of just renaming.
Second, here are some script examples:
You have another example using a similar technique, using git rev-parse
and git diff-index
, and the empty tree I mentioned before:
#!/bin/sh
if git rev-parse --verify HEAD >/dev/null 2>&1; then
against=HEAD
else
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
for FILE in `git diff-index --name-status $against -- | cut -c3-` ; do
# Check if the file contains 'debugger'
if [ "grep 'debugger' $FILE" ]
then
echo $FILE ' contains debugger!'
exit 1
fi
done
exit
The comments on this gist mention:
On my system, if [ "grep 'debugger' $FILE" ]
always evaluates to true
.
Changing it to if grep -q 'debugger' "$FILE"
fixes that.
A more recent example:
#!/bin/bash
# Pre commit hook that prevents FORBIDDEN code from being commited.
# Add unwanted code to the FORBIDDEN array as necessary
FILES_PATTERN='\.(rb|js|coffee)(\..+)?$'
FORBIDDEN=( debugger ruby-debug )
for i in "${FORBIDDEN[@]}"
do
git diff --cached --name-only| grep ".js" |xargs sed 's/ //g'|grep "ha_mobile.debug=true" && \
echo 'COMMIT REJECTED Found ha_mobile.debug=true references. Please remove them before commiting' && exit 1
git diff --cached --name-only | \
grep -E $FILES_PATTERN | \
GREP_COLOR='4;5;37;41' xargs grep --color --with-filename -n $i && \
echo 'COMMIT REJECTED Found' $i 'references. Please remove them before commiting' && exit 1
done
exit 0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With