blob: 0bd89e6506a1b2bc8308dceb20f14a0da8800768 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
#!/bin/bash
if [ "$#" -lt 1 ]; then
printf 'Usage: %s <commit range>\n', "$0" 1>&2
exit 1
fi
commits=$(git rev-list --no-merges -i --grep='^[[:space:]]*Fixes:' "$@")
if [ -z "$commits" ]; then
exit 0
fi
# This should be a git tree that contains *only* Linus' tree
Linus_tree="${HOME}/kernels/linus.git"
split_re='^([[:xdigit:]]+)[[:space:]]+(.*)$'
nl=$'\n'
# Strip the leading and training spaces from a string
strip_spaces()
{
[[ "$1" =~ ^[[:space:]]*(.*[^[:space:]])[[:space:]]*$ ]]
echo "${BASH_REMATCH[1]}"
}
for c in $commits; do
commit_log=$(git log -1 --format='%h ("%s")' "$c")
commit_msg="In commit
$commit_log
"
fixes_lines=$(git log -1 --format='%B' "$c" |
grep -i '^[[:space:]]*Fixes:')
while read -r fline; do
f=$(echo "$fline" | sed 's/^[[:space:]]*Fixes:[[:space:]]*//i')
fixes_msg="Fixes tag
$fline
has these problem(s):
"
sha=
subject=
msg=
[[ "$f" =~ $split_re ]]
sha="${BASH_REMATCH[1]}"
subject="${BASH_REMATCH[2]}"
if [ -z "$sha" ]; then
printf '%s%s - %s\n' "$commit_msg" "$fixes_msg" 'No SHA1 recognised'
commit_msg=''
continue
fi
if ! git rev-parse -q --verify "$sha" >/dev/null; then
printf '%s%s - %s\n' "$commit_msg" "$fixes_msg" 'Target SHA1 does not exist'
commit_msg=''
continue
fi
if [ "${#sha}" -lt 12 ]; then
msg="${msg:+${msg}${nl}} - SHA1 should be at least 12 digits long"
fi
# reduce the subject to the part between () if there
if [[ "$subject" =~ ^\((.*)\) ]]; then
subject="${BASH_REMATCH[1]}"
elif [[ "$subject" =~ ^\((.*) ]]; then
subject="${BASH_REMATCH[1]}"
msg="${msg:+${msg}${nl}} - Subject has leading but no trailing parentheses"
fi
# strip matching quotes at the start and end of the subject
# the unicode characters in the classes are
# U+201C LEFT DOUBLE QUOTATION MARK
# U+201D RIGHT DOUBLE QUOTATION MARK
# U+2018 LEFT SINGLE QUOTATION MARK
# U+2019 RIGHT SINGLE QUOTATION MARK
re1=$'^[\"\u201C](.*)[\"\u201D]$'
re2=$'^[\'\u2018](.*)[\'\u2019]$'
re3=$'^[\"\'\u201C\u2018](.*)$'
if [[ "$subject" =~ $re1 ]]; then
subject="${BASH_REMATCH[1]}"
elif [[ "$subject" =~ $re2 ]]; then
subject="${BASH_REMATCH[1]}"
elif [[ "$subject" =~ $re3 ]]; then
subject="${BASH_REMATCH[1]}"
msg="${msg:+${msg}${nl}} - Subject has leading but no trailing quotes"
fi
subject=$(strip_spaces "$subject")
target_subject=$(git log -1 --format='%s' "$sha")
target_subject=$(strip_spaces "$target_subject")
# match with ellipses
case "$subject" in
*...) subject="${subject%...}"
target_subject="${target_subject:0:${#subject}}"
;;
...*) subject="${subject#...}"
target_subject="${target_subject: -${#subject}}"
;;
*\ ...\ *)
s1="${subject% ... *}"
s2="${subject#* ... }"
subject="$s1 $s2"
t1="${target_subject:0:${#s1}}"
t2="${target_subject: -${#s2}}"
target_subject="$t1 $t2"
;;
esac
subject=$(strip_spaces "$subject")
target_subject=$(strip_spaces "$target_subject")
if [ "$subject" != "${target_subject:0:${#subject}}" ]; then
msg="${msg:+${msg}${nl}} - Subject does not match target commit subject"
fi
lsha=$(cd "$Linus_tree" && git rev-parse -q --verify "$sha")
if [ -z "$lsha" ]; then
count=$(git rev-list --count "$sha".."$c")
if [ "$count" -eq 0 ]; then
msg="${msg:+${msg}${nl}} - Target is not an ancestor of this commit"
fi
fi
if [ "$msg" ]; then
printf '%s%s%s\n' "$commit_msg" "$fixes_msg" "$msg"
commit_msg=''
fi
done <<< "$fixes_lines"
done
exit 0
|