diff options
author | David Pursehouse <dpursehouse@collab.net> | 2020-02-16 12:38:36 +0900 |
---|---|---|
committer | David Pursehouse <dpursehouse@collab.net> | 2020-02-17 03:57:19 +0000 |
commit | 3995ebd8c1569f2c3e59c33593fed611a923f428 (patch) | |
tree | 5ad3c6178c8cacbdec1a4f6be0bc2df113ca4d99 | |
parent | b57e633433eaf32f9c2e3f398937f99a5319869c (diff) | |
download | git-repo-3995ebd8c1569f2c3e59c33593fed611a923f428.tar.gz |
Update commit-msg hook to version from Gerrit 3.1.3
Includes the following commits (redacted to those that are relevant):
da300bd9bd8 - Do not create a change id if gerrit.createChangeId == false
731eb42b8ae - Do not strip out "-- >8 --" comment in commit-msg hook
627d07c2bfc - Handle messages with only comments in the commit-msg hook
68296f71804 - Simplify the hook script using git-interpret-trailers
Change-Id: I7a82836495427df3c5437ba88a9576b47629065f
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/255393
Reviewed-by: Mike Frysinger <vapier@google.com>
Tested-by: David Pursehouse <dpursehouse@collab.net>
-rwxr-xr-x | hooks/commit-msg | 218 |
1 files changed, 45 insertions, 173 deletions
diff --git a/hooks/commit-msg b/hooks/commit-msg index d9bb188b..70d67eaf 100755 --- a/hooks/commit-msg +++ b/hooks/commit-msg | |||
@@ -1,5 +1,5 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | # From Gerrit Code Review 2.14.6 | 2 | # From Gerrit Code Review 3.1.3 |
3 | # | 3 | # |
4 | # Part of Gerrit Code Review (https://www.gerritcodereview.com/) | 4 | # Part of Gerrit Code Review (https://www.gerritcodereview.com/) |
5 | # | 5 | # |
@@ -16,176 +16,48 @@ | |||
16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
17 | # See the License for the specific language governing permissions and | 17 | # See the License for the specific language governing permissions and |
18 | # limitations under the License. | 18 | # limitations under the License. |
19 | # | ||
20 | |||
21 | unset GREP_OPTIONS | ||
22 | |||
23 | CHANGE_ID_AFTER="Bug|Depends-On|Issue|Test|Feature|Fixes|Fixed" | ||
24 | MSG="$1" | ||
25 | |||
26 | # Check for, and add if missing, a unique Change-Id | ||
27 | # | ||
28 | add_ChangeId() { | ||
29 | clean_message=`sed -e ' | ||
30 | /^diff --git .*/{ | ||
31 | s/// | ||
32 | q | ||
33 | } | ||
34 | /^Signed-off-by:/d | ||
35 | /^#/d | ||
36 | ' "$MSG" | git stripspace` | ||
37 | if test -z "$clean_message" | ||
38 | then | ||
39 | return | ||
40 | fi | ||
41 | |||
42 | # Do not add Change-Id to temp commits | ||
43 | if echo "$clean_message" | head -1 | grep -q '^\(fixup\|squash\)!' | ||
44 | then | ||
45 | return | ||
46 | fi | ||
47 | |||
48 | if test "false" = "`git config --bool --get gerrit.createChangeId`" | ||
49 | then | ||
50 | return | ||
51 | fi | ||
52 | |||
53 | # Does Change-Id: already exist? if so, exit (no change). | ||
54 | if grep -i '^Change-Id:' "$MSG" >/dev/null | ||
55 | then | ||
56 | return | ||
57 | fi | ||
58 | |||
59 | id=`_gen_ChangeId` | ||
60 | T="$MSG.tmp.$$" | ||
61 | AWK=awk | ||
62 | if [ -x /usr/xpg4/bin/awk ]; then | ||
63 | # Solaris AWK is just too broken | ||
64 | AWK=/usr/xpg4/bin/awk | ||
65 | fi | ||
66 | |||
67 | # Get core.commentChar from git config or use default symbol | ||
68 | commentChar=`git config --get core.commentChar` | ||
69 | commentChar=${commentChar:-#} | ||
70 | |||
71 | # How this works: | ||
72 | # - parse the commit message as (textLine+ blankLine*)* | ||
73 | # - assume textLine+ to be a footer until proven otherwise | ||
74 | # - exception: the first block is not footer (as it is the title) | ||
75 | # - read textLine+ into a variable | ||
76 | # - then count blankLines | ||
77 | # - once the next textLine appears, print textLine+ blankLine* as these | ||
78 | # aren't footer | ||
79 | # - in END, the last textLine+ block is available for footer parsing | ||
80 | $AWK ' | ||
81 | BEGIN { | ||
82 | # while we start with the assumption that textLine+ | ||
83 | # is a footer, the first block is not. | ||
84 | isFooter = 0 | ||
85 | footerComment = 0 | ||
86 | blankLines = 0 | ||
87 | } | ||
88 | |||
89 | # Skip lines starting with commentChar without any spaces before it. | ||
90 | /^'"$commentChar"'/ { next } | ||
91 | |||
92 | # Skip the line starting with the diff command and everything after it, | ||
93 | # up to the end of the file, assuming it is only patch data. | ||
94 | # If more than one line before the diff was empty, strip all but one. | ||
95 | /^diff --git / { | ||
96 | blankLines = 0 | ||
97 | while (getline) { } | ||
98 | next | ||
99 | } | ||
100 | |||
101 | # Count blank lines outside footer comments | ||
102 | /^$/ && (footerComment == 0) { | ||
103 | blankLines++ | ||
104 | next | ||
105 | } | ||
106 | |||
107 | # Catch footer comment | ||
108 | /^\[[a-zA-Z0-9-]+:/ && (isFooter == 1) { | ||
109 | footerComment = 1 | ||
110 | } | ||
111 | |||
112 | /]$/ && (footerComment == 1) { | ||
113 | footerComment = 2 | ||
114 | } | ||
115 | |||
116 | # We have a non-blank line after blank lines. Handle this. | ||
117 | (blankLines > 0) { | ||
118 | print lines | ||
119 | for (i = 0; i < blankLines; i++) { | ||
120 | print "" | ||
121 | } | ||
122 | |||
123 | lines = "" | ||
124 | blankLines = 0 | ||
125 | isFooter = 1 | ||
126 | footerComment = 0 | ||
127 | } | ||
128 | |||
129 | # Detect that the current block is not the footer | ||
130 | (footerComment == 0) && (!/^\[?[a-zA-Z0-9-]+:/ || /^[a-zA-Z0-9-]+:\/\//) { | ||
131 | isFooter = 0 | ||
132 | } | ||
133 | |||
134 | { | ||
135 | # We need this information about the current last comment line | ||
136 | if (footerComment == 2) { | ||
137 | footerComment = 0 | ||
138 | } | ||
139 | if (lines != "") { | ||
140 | lines = lines "\n"; | ||
141 | } | ||
142 | lines = lines $0 | ||
143 | } | ||
144 | |||
145 | # Footer handling: | ||
146 | # If the last block is considered a footer, splice in the Change-Id at the | ||
147 | # right place. | ||
148 | # Look for the right place to inject Change-Id by considering | ||
149 | # CHANGE_ID_AFTER. Keys listed in it (case insensitive) come first, | ||
150 | # then Change-Id, then everything else (eg. Signed-off-by:). | ||
151 | # | ||
152 | # Otherwise just print the last block, a new line and the Change-Id as a | ||
153 | # block of its own. | ||
154 | END { | ||
155 | unprinted = 1 | ||
156 | if (isFooter == 0) { | ||
157 | print lines "\n" | ||
158 | lines = "" | ||
159 | } | ||
160 | changeIdAfter = "^(" tolower("'"$CHANGE_ID_AFTER"'") "):" | ||
161 | numlines = split(lines, footer, "\n") | ||
162 | for (line = 1; line <= numlines; line++) { | ||
163 | if (unprinted && match(tolower(footer[line]), changeIdAfter) != 1) { | ||
164 | unprinted = 0 | ||
165 | print "Change-Id: I'"$id"'" | ||
166 | } | ||
167 | print footer[line] | ||
168 | } | ||
169 | if (unprinted) { | ||
170 | print "Change-Id: I'"$id"'" | ||
171 | } | ||
172 | }' "$MSG" > "$T" && mv "$T" "$MSG" || rm -f "$T" | ||
173 | } | ||
174 | _gen_ChangeIdInput() { | ||
175 | echo "tree `git write-tree`" | ||
176 | if parent=`git rev-parse "HEAD^0" 2>/dev/null` | ||
177 | then | ||
178 | echo "parent $parent" | ||
179 | fi | ||
180 | echo "author `git var GIT_AUTHOR_IDENT`" | ||
181 | echo "committer `git var GIT_COMMITTER_IDENT`" | ||
182 | echo | ||
183 | printf '%s' "$clean_message" | ||
184 | } | ||
185 | _gen_ChangeId() { | ||
186 | _gen_ChangeIdInput | | ||
187 | git hash-object -t commit --stdin | ||
188 | } | ||
189 | |||
190 | 19 | ||
191 | add_ChangeId | 20 | # avoid [[ which is not POSIX sh. |
21 | if test "$#" != 1 ; then | ||
22 | echo "$0 requires an argument." | ||
23 | exit 1 | ||
24 | fi | ||
25 | |||
26 | if test ! -f "$1" ; then | ||
27 | echo "file does not exist: $1" | ||
28 | exit 1 | ||
29 | fi | ||
30 | |||
31 | # Do not create a change id if requested | ||
32 | if test "false" = "`git config --bool --get gerrit.createChangeId`" ; then | ||
33 | exit 0 | ||
34 | fi | ||
35 | |||
36 | # $RANDOM will be undefined if not using bash, so don't use set -u | ||
37 | random=$( (whoami ; hostname ; date; cat $1 ; echo $RANDOM) | git hash-object --stdin) | ||
38 | dest="$1.tmp.${random}" | ||
39 | |||
40 | trap 'rm -f "${dest}"' EXIT | ||
41 | |||
42 | if ! git stripspace --strip-comments < "$1" > "${dest}" ; then | ||
43 | echo "cannot strip comments from $1" | ||
44 | exit 1 | ||
45 | fi | ||
46 | |||
47 | if test ! -s "${dest}" ; then | ||
48 | echo "file is empty: $1" | ||
49 | exit 1 | ||
50 | fi | ||
51 | |||
52 | # Avoid the --in-place option which only appeared in Git 2.8 | ||
53 | # Avoid the --if-exists option which only appeared in Git 2.15 | ||
54 | if ! git -c trailer.ifexists=doNothing interpret-trailers \ | ||
55 | --trailer "Change-Id: I${random}" < "$1" > "${dest}" ; then | ||
56 | echo "cannot insert change-id line in $1" | ||
57 | exit 1 | ||
58 | fi | ||
59 | |||
60 | if ! mv "${dest}" "$1" ; then | ||
61 | echo "cannot mv ${dest} to $1" | ||
62 | exit 1 | ||
63 | fi | ||