#!/bin/bash # # This is a modified version of the stock git sample pre-commit hook. # In addition to the stock whitespace error checks, this one will also # reject any commits that try to insert TABs to *.c or *.h files. if git rev-parse --verify HEAD >/dev/null 2>&1 then against=HEAD else # Initial commit: diff against an empty tree object against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 fi # If you want to allow non-ascii filenames set this variable to true. allownonascii=$(git config hooks.allownonascii) # Redirect output to stderr. exec 1>&2 # Cross platform projects tend to avoid non-ascii filenames; prevent # them from being added to the repository. We exploit the fact that the # printable range starts at the space character and ends with tilde. if [ "$allownonascii" != "true" ] && # Note that the use of brackets around a tr range is ok here, (it's # even required, for portability to Solaris 10's /usr/bin/tr), since # the square bracket bytes happen to fall in the designated range. test $(git diff --cached --name-only --diff-filter=A -z $against | LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 then echo "Error: Attempt to add a non-ascii file name." echo echo "This can cause problems if you want to work" echo "with people on other platforms." echo echo "To be portable it is advisable to rename the file ..." echo echo "If you know what you are doing you can disable this" echo "check using:" echo echo " git config hooks.allownonascii true" echo exit 1 fi # If there are whitespace errors, print the offending file names and fail. git diff-index --check --cached $against -- status=$? if [ "$status" != "0" ]; then echo "" echo "WARNING:" echo "WARNING: Your commit would introduce whitespace errors and was" echo "WARNING: hence rejected. Please fix those errors before trying" echo "WARNING: to commit again." echo "WARNING:" exit 1 fi # Check if any TABS have been added to .c or .h files... file="" git diff --cached $against | \ while read -r line; do case $line in diff\ --git\ a/*) # 1st diff line, dig out file name file="${line##*b/}" echo "Checking changes to $file..." continue ;; esac case $file in *.h|*.c) ;; # we process C source code, *) continue;; # and skip any other files esac case $line in +*\ *) ;; # we flag insertions containing a TAB, *) continue;; # and skip all other changes esac echo "WARNING:" echo "WARNING: In $file: ($line)" echo "WARNING:" echo "WARNING: Your commit would introduce TABS in a *.c or *.h" echo "WARNING: file and was hence rejected. We prefer not to use" echo "WARNING: TABS in source code to avoid TAB-size dependent" echo "WARNING: incorrect indentation to sneak in. Please fix those" echo "WARNING: errors before trying to commit again." echo "WARNING:" exit 1 done # Check if this commit attempts to mix changes to autogenerated files # files with changes to ordinary file and give the user a gentle push # against the idea... auto="`git diff --cached $against | grep ^diff | grep -e -func-info.c`" plain="`git diff --cached $against | grep ^diff | grep -v -e -func-info.c`" if [ -n "$auto" -a -n "$plain" ]; then echo "WARNING:" echo "WARNING: Your commit tries to mix changes to ordinary and" echo "WARNING: automatically generated files. Doing so makes it" echo "WARNING: more difficult to merge your changes with changes" echo "WARNING: of others working in parallel with you." echo "WARNING:" echo "WARNING: Please consider leaving out the following files" echo "WARNING: from this commit and separating changes to them" echo "WARNING: to a subsequent commit of its own:" echo "WARNING:" git diff --cached $against | grep ^diff | grep func-info.c | \ sed 's#^diff .* b/#WARNING: #g' echo "WARNING:" echo "WARNING: In case you really need to commit all of these" echo "WARNING: changes together you can disable this check by" echo "WARNING: passing the -n option to 'git commit'." exit 1 fi exit $?