]> code.delx.au - gnu-emacs/blob - build-aux/git-hooks/commit-msg
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs.
[gnu-emacs] / build-aux / git-hooks / commit-msg
1 #!/bin/sh
2 # Check the format of GNU Emacs change log entries.
3
4 # Copyright 2014 Free Software Foundation, Inc.
5
6 # This file is part of GNU Emacs.
7
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.
12
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.
17
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/>.
20
21 # Written by Paul Eggert.
22
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
28 fi
29
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
36 `
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
41 `
42 if test "$at_sign" = @; then
43 LC_ALL=en_US.UTF-8; export LC_ALL
44 fi
45 fi
46
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]"
60 }
61 }
62
63 /^#/ { next }
64
65 !/^.*$/ {
66 print "Invalid character (not UTF-8) in commit message"
67 status = 1
68 }
69
70 nlines == 0 && $0 !~ non_space { next }
71
72 { nlines++ }
73
74 nlines == 1 {
75 # Ignore special markers used by "git rebase --autosquash".
76 if (! sub(/^fixup! /, ""))
77 sub(/^squash! /, "")
78
79 if ($0 ~ "^" space) {
80 print "White space at start of commit message'\''s first line"
81 status = 1
82 }
83 }
84
85 nlines == 2 && $0 ~ non_space {
86 print "Nonempty second line in commit message"
87 status = 1
88 }
89
90 {
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)
96 }
97 }
98
99 78 < length && $0 ~ space {
100 print "Line longer than 78 characters in commit message"
101 status = 1
102 }
103
104 140 < length {
105 print "Word longer than 140 characters in commit message"
106 status = 1
107 }
108
109 /^Signed-off-by: / {
110 print "'\''Signed-off-by:'\'' in commit message"
111 status = 1
112 }
113
114 $0 ~ non_print {
115 print "Unprintable character in commit message"
116 status = 1
117 }
118
119 END {
120 if (nlines == 0) {
121 print "Empty commit message"
122 status = 1
123 }
124 exit status
125 }
126 ' <"$1"