|
1 | 1 | #!/bin/bash
|
2 | 2 | #
|
3 |
| -# An example hook script to verify what is about to be committed. |
| 3 | +# Git pre-commit hook script to verify what is about to be committed. |
4 | 4 | # Called by "git commit" with no arguments. The hook should
|
5 | 5 | # exit with non-zero status after issuing an appropriate message if
|
6 | 6 | # it wants to stop the commit.
|
7 | 7 | #
|
8 |
| -# To enable this hook, rename this file to "pre-commit". |
| 8 | +# Checks performed by this script include: |
| 9 | +# |
| 10 | +# 1. Verifying that all text-based files end in a single new line character (appropriate for the given OS) |
| 11 | +# 2. No spurious, extra blank lines are at the end of a file textfile |
| 12 | +# 3. No files with non-ascii names are added to the git repo unless explicitly enabled in the git-config |
| 13 | +# 4. All files being committed conform to the git-config whitespace policy |
| 14 | + |
| 15 | +set -o errexit |
| 16 | +set -o pipefail |
| 17 | +set -o nounset |
| 18 | +set -o errtrace |
| 19 | + |
| 20 | +__file=pre-commit |
| 21 | + |
| 22 | +err_report() { |
| 23 | + error_code=$? |
| 24 | + echo 2>&1 "Error in $__file in function $1 on line $2" |
| 25 | + exit $error_code |
| 26 | +} |
| 27 | + |
| 28 | +trap 'err_report "${FUNCNAME:-.}" $LINENO' ERR |
9 | 29 |
|
10 | 30 | function ends_with_newline() {
|
11 |
| - test ! -s "$1" || test $(tail -r -c1 "$1" | xxd -ps) = "0a" |
| 31 | + [[ ! -s "$1" ]] || [[ "$(tail -c1 "$1" | xxd -ps)" = "0a" ]] |
12 | 32 | }
|
13 | 33 |
|
14 | 34 | function ends_with_single_new_line () {
|
15 |
| - tail -2 "$1" | ( read x && read y && ! grep '^[[:blank:]]\+$' <<<$x >/dev/null) |
| 35 | + ends_with_newline "$1" && tail -1 "$1" | grep '[^[:blank:]]' >/dev/null 2>&1 |
16 | 36 | }
|
17 | 37 |
|
18 |
| -if git rev-parse --verify HEAD >/dev/null 2>&1 |
19 |
| -then |
20 |
| - against=HEAD |
| 38 | +if git rev-parse --verify HEAD >/dev/null 2>&1 ; then |
| 39 | + against=HEAD |
21 | 40 | else
|
22 |
| - # Initial commit: diff against an empty tree object |
23 |
| - against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 |
| 41 | + # Initial commit: diff against an empty tree object |
| 42 | + against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 |
24 | 43 | fi
|
25 | 44 |
|
26 | 45 | # if we are in the middle of merging skip hooks
|
27 |
| -MERGING=$(git rev-parse MERGE_HEAD 2>&1) |
28 |
| -if [[ $? == 0 ]]; then |
| 46 | +if git rev-parse MERGE_HEAD >/dev/null 2>&1 ; then |
29 | 47 | exit 0
|
30 | 48 | fi
|
31 | 49 |
|
32 |
| -# if we are in the middle of merging skip hooks |
33 |
| -PICKING=$(git rev-parse CHERRY_PICK_HEAD 2>&1) |
34 |
| -if [[ $? == 0 ]]; then |
| 50 | +if git rev-parse CHERRY_PICK_HEAD >/dev/null 2>&1 ; then |
35 | 51 | exit 0
|
36 | 52 | fi
|
37 | 53 |
|
38 | 54 | # If you want to allow non-ASCII filenames set this variable to true.
|
39 |
| -allownonascii=$(git config --bool hooks.allownonascii) |
| 55 | +allownonascii=$(git config --bool hooks.allownonascii || true) |
40 | 56 |
|
41 | 57 | # Redirect output to stderr.
|
42 | 58 | exec 1>&2
|
43 | 59 |
|
44 |
| -let status=0 |
| 60 | +status=0 |
45 | 61 | # Cross platform projects tend to avoid non-ASCII filenames; prevent
|
46 | 62 | # them from being added to the repository. We exploit the fact that the
|
47 | 63 | # printable range starts at the space character and ends with tilde.
|
48 | 64 | if [ "$allownonascii" != "true" ] &&
|
49 |
| - # Note that the use of brackets around a tr range is ok here, (it's |
50 |
| - # even required, for portability to Solaris 10's /usr/bin/tr), since |
51 |
| - # the square bracket bytes happen to fall in the designated range. |
52 |
| - test $(git diff --cached --name-only --diff-filter=A -z $against | |
53 |
| - LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 |
| 65 | + # Note that the use of brackets around a tr range is ok here, (it's |
| 66 | + # even required, for portability to Solaris 10's /usr/bin/tr), since |
| 67 | + # the square bracket bytes happen to fall in the designated range. |
| 68 | + (( "$(git diff --cached --name-only --diff-filter=A -z $against | |
| 69 | + LC_ALL=C tr -d '[ -~]\0' | wc -c)" != 0 )) |
54 | 70 | then
|
55 |
| - cat &>2 <<\EOF |
56 |
| -Error: Attempt to add a non-ASCII file name. |
57 |
| -
|
58 |
| -This can cause problems if you want to work with people on other platforms. |
59 |
| -
|
60 |
| -To be portable it is advisable to rename the file. |
61 |
| -
|
62 |
| -If you know what you are doing you can disable this check using: |
63 |
| -
|
64 |
| - git config hooks.allownonascii true |
| 71 | + cat <<-EOF |
| 72 | + Error: Attempt to add a non-ASCII file name. |
| 73 | + This can cause problems if you want to work with people on other platforms. |
| 74 | + To be portable it is advisable to rename the file. |
| 75 | + If you know what you are doing you can disable this check using: |
| 76 | + git config hooks.allownonascii true |
65 | 77 | EOF
|
66 |
| - let status=1 |
| 78 | + status=1 |
67 | 79 | fi
|
68 | 80 |
|
69 | 81 | # If there is a file that does not end with a newline, print its name and fail.
|
70 | 82 | for f in $(git diff-index --name-status --cached $against | grep -v ^D | cut -c3-); do
|
71 |
| - if [[ "$f" =~ ([.](h|m|c|rb|sh|py|txt|md|f90|F90|cmake|x64|csh)|makefile|Makefile)$ ]] || |
| 83 | + if [[ "$f" =~ ([.](h|m|c|rb|sh|py|txt|md|f90|F90|cmake|x64|csh|txt)|makefile|Makefile)$ ]] || |
72 | 84 | head -n 1 | grep '^#!/'; then
|
73 | 85 | if ! ends_with_newline "$f"; then
|
74 |
| - echo &>2 "No newline at end of file: $f" |
| 86 | + echo "No newline at end of file: $f" |
| 87 | + echo "" |
| 88 | + status=1 |
| 89 | + fi |
| 90 | + if ! ends_with_single_new_line "$f"; then |
| 91 | + echo "multiple blank lines at end of file: $f" |
75 | 92 | echo ""
|
76 |
| - let status=1 |
| 93 | + status=1 |
77 | 94 | fi
|
78 | 95 | fi
|
79 | 96 | done
|
80 | 97 |
|
81 | 98 | # If there are whitespace errors, print the offending file names and fail.
|
82 |
| -git diff-index --check --cached $against -- || (let status=1 echo 'white space violations found') |
| 99 | +if ! git diff-index --check --cached $against -- ; then |
| 100 | + status=1 |
| 101 | + echo "white space violations found" |
| 102 | +fi |
| 103 | + |
83 | 104 |
|
84 | 105 | if [[ $status = 0 ]]; then
|
85 |
| - exit 0 |
| 106 | + exit 0 |
86 | 107 | fi
|
87 | 108 |
|
88 | 109 | exit 1
|
0 commit comments