Have commit-msg report commit failure
[emacs.git] / build-aux / git-hooks / commit-msg
blob6721d53a582363930c05ab30ecd4ad4edd9f2021
1 #!/bin/sh
2 # Check the format of GNU Emacs change log entries.
4 # Copyright 2014-2015 Free Software Foundation, Inc.
6 # This file is part of GNU Emacs.
8 # GNU Emacs is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
13 # GNU Emacs is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
21 # Written by Paul Eggert.
23 # Prefer gawk if available, as it handles NUL bytes properly.
24 if type gawk >/dev/null 2>&1; then
25 awk=gawk
26 else
27 awk=awk
30 # Use a UTF-8 locale if available, so that the UTF-8 check works.
31 # Use U+00A2 CENT SIGN to test whether the locale works.
32 cent_sign_utf8_octal='\302\242'
33 at_sign=`
34 printf "${cent_sign_utf8_octal}@" |
35 $awk '{print substr($0, 2)}' 2>/dev/null
37 if test "$at_sign" != @; then
38 at_sign=`
39 printf "${cent_sign_utf8_octal}@" |
40 LC_ALL=en_US.UTF-8 $awk '{print substr($0, 2)}' 2>/dev/null
42 if test "$at_sign" = @; then
43 LC_ALL=en_US.UTF-8; export LC_ALL
47 # Check the log entry.
48 exec $awk '
49 BEGIN {
50 if (" " ~ /[[:space:]]/) {
51 space = "[[:space:]]"
52 non_space = "[^[:space:]]"
53 non_print = "[^[:print:]]"
54 } else {
55 # mawk 1.3.3 does not support POSIX bracket expressions.
56 # Approximate them as best we can.
57 space = "[ \f\n\r\t\v]"
58 non_space = "[^ \f\n\r\t\v]"
59 non_print = "[\1-\37\177]"
63 /^#/ { next }
65 !/^.*$/ {
66 print "Invalid character (not UTF-8) in commit message"
67 status = 1
70 nlines == 0 && $0 !~ non_space { next }
72 { nlines++ }
74 nlines == 1 {
75 # Ignore special markers used by "git rebase --autosquash".
76 if (! sub(/^fixup! /, ""))
77 sub(/^squash! /, "")
79 if ($0 ~ "^" space) {
80 print "White space at start of commit message'\''s first line"
81 status = 1
85 nlines == 2 && $0 ~ non_space {
86 print "Nonempty second line in commit message"
87 status = 1
91 # Expand tabs to spaces for length calculations etc.
92 while (match($0, /\t/)) {
93 before_tab = substr($0, 1, RSTART - 1)
94 after_tab = substr($0, RSTART + 1)
95 $0 = sprintf("%s%*s%s", before_tab, 8 - (RSTART - 1) % 8, "", after_tab)
99 78 < length && $0 ~ space {
100 print "Line longer than 78 characters in commit message"
101 status = 1
104 140 < length {
105 print "Word longer than 140 characters in commit message"
106 status = 1
109 /^Signed-off-by: / {
110 print "'\''Signed-off-by:'\'' in commit message"
111 status = 1
114 $0 ~ non_print {
115 print "Unprintable character in commit message"
116 status = 1
119 END {
120 if (nlines == 0) {
121 print "Empty commit message"
122 status = 1
124 if (status != 0) {
125 print "Commit aborted; please see the file 'CONTRIBUTE'"
127 exit status
129 ' <"$1"