Serenity Operating System
1#!/usr/bin/env bash
2
3# the file containing the commit message is passed as the first argument
4commit_file="$1"
5commit_message=$(cat "$commit_file")
6
7error() {
8 echo -e "\033[0;31m$1:\033[0m"
9 echo "$commit_message"
10 exit 1
11}
12
13# fail if the commit message contains windows style line breaks (carriage returns)
14if grep -q -U $'\x0D' "$commit_file"; then
15 error "Commit message contains CRLF line breaks (only unix-style LF linebreaks are allowed)"
16fi
17
18line_number=0
19while read -r line; do
20 # break on git cut line, used by git commit --verbose
21 if [[ "$line" == "# ------------------------ >8 ------------------------" ]]; then
22 break
23 fi
24
25 # ignore comment lines
26 [[ "$line" =~ ^#.* ]] && continue
27 # ignore overlong 'fixup!' commit descriptions
28 [[ "$line" =~ ^fixup!\ .* ]] && continue
29
30 ((line_number += 1))
31 line_length=${#line}
32
33 if [[ $line_number -eq 2 ]] && [[ $line_length -ne 0 ]]; then
34 error "Empty line between commit title and body is missing"
35 fi
36
37 merge_commit_pattern="^Merge branch"
38 if [[ $line_number -eq 1 ]] && (echo "$line" | grep -E -q "$merge_commit_pattern"); then
39 error "Commit is a git merge commit, use the rebase command instead"
40 fi
41
42 category_pattern='^(Revert "|\S+: )'
43 if [[ $line_number -eq 1 ]] && (echo "$line" | grep -E -v -q "$category_pattern"); then
44 error "Missing category in commit title (if this is a fix up of a previous commit, it should be squashed)"
45 fi
46
47 title_case_pattern="^\S.*?: [A-Z0-9]"
48 if [[ $line_number -eq 1 ]] && (echo "$line" | grep -E -v -q "$title_case_pattern"); then
49 error "First word of commit after the subsystem is not capitalized"
50 fi
51
52 if [[ $line_number -eq 1 ]] && [[ "$line" =~ \.$ ]]; then
53 error "Commit title ends in a period"
54 fi
55
56 url_pattern="([a-z]+:\/\/)?(([a-zA-Z0-9_]|-)+\.)+[a-z]{2,}(:\d+)?([a-zA-Z_0-9@:%\+.~\?&\/=]|-)+"
57 if [[ $line_length -gt 72 ]] && (echo "$line" | grep -E -v -q "$url_pattern"); then
58 error "Commit message lines are too long (maximum allowed is 72 characters)"
59 fi
60
61 if [[ "$line" == "Signed-off-by: "* ]]; then
62 error "Commit body contains a Signed-off-by tag"
63 fi
64
65done <"$commit_file"
66exit 0