nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | #!/bin/sh |
2 | # From Gerrit Code Review 2.9-rc1-172-gd621a9e |
||
3 | # |
||
4 | # Part of Gerrit Code Review (http://code.google.com/p/gerrit/) |
||
5 | # |
||
6 | # Copyright (C) 2009 The Android Open Source Project |
||
7 | # |
||
8 | # Licensed under the Apache License, Version 2.0 (the "License"); |
||
9 | # you may not use this file except in compliance with the License. |
||
10 | # You may obtain a copy of the License at |
||
11 | # |
||
12 | # http://www.apache.org/licenses/LICENSE-2.0 |
||
13 | # |
||
14 | # Unless required by applicable law or agreed to in writing, software |
||
15 | # distributed under the License is distributed on an "AS IS" BASIS, |
||
16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||
17 | # See the License for the specific language governing permissions and |
||
18 | # limitations under the License. |
||
19 | # |
||
20 | |||
21 | unset GREP_OPTIONS |
||
22 | |||
23 | CHANGE_ID_AFTER="Bug|Issue" |
||
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 | if test "false" = "`git config --bool --get gerrit.createChangeId`" |
||
43 | then |
||
44 | return |
||
45 | fi |
||
46 | |||
47 | # Does Change-Id: already exist? if so, exit (no change). |
||
48 | if grep -i '^Change-Id:' "$MSG" >/dev/null |
||
49 | then |
||
50 | return |
||
51 | fi |
||
52 | |||
53 | id=`_gen_ChangeId` |
||
54 | T="$MSG.tmp.$$" |
||
55 | AWK=awk |
||
56 | if [ -x /usr/xpg4/bin/awk ]; then |
||
57 | # Solaris AWK is just too broken |
||
58 | AWK=/usr/xpg4/bin/awk |
||
59 | fi |
||
60 | |||
61 | # How this works: |
||
62 | # - parse the commit message as (textLine+ blankLine*)* |
||
63 | # - assume textLine+ to be a footer until proven otherwise |
||
64 | # - exception: the first block is not footer (as it is the title) |
||
65 | # - read textLine+ into a variable |
||
66 | # - then count blankLines |
||
67 | # - once the next textLine appears, print textLine+ blankLine* as these |
||
68 | # aren't footer |
||
69 | # - in END, the last textLine+ block is available for footer parsing |
||
70 | $AWK ' |
||
71 | BEGIN { |
||
72 | # while we start with the assumption that textLine+ |
||
73 | # is a footer, the first block is not. |
||
74 | isFooter = 0 |
||
75 | footerComment = 0 |
||
76 | blankLines = 0 |
||
77 | } |
||
78 | |||
79 | # Skip lines starting with "#" without any spaces before it. |
||
80 | /^#/ { next } |
||
81 | |||
82 | # Skip the line starting with the diff command and everything after it, |
||
83 | # up to the end of the file, assuming it is only patch data. |
||
84 | # If more than one line before the diff was empty, strip all but one. |
||
85 | /^diff --git / { |
||
86 | blankLines = 0 |
||
87 | while (getline) { } |
||
88 | next |
||
89 | } |
||
90 | |||
91 | # Count blank lines outside footer comments |
||
92 | /^$/ && (footerComment == 0) { |
||
93 | blankLines++ |
||
94 | next |
||
95 | } |
||
96 | |||
97 | # Catch footer comment |
||
98 | /^\[[a-zA-Z0-9-]+:/ && (isFooter == 1) { |
||
99 | footerComment = 1 |
||
100 | } |
||
101 | |||
102 | /]$/ && (footerComment == 1) { |
||
103 | footerComment = 2 |
||
104 | } |
||
105 | |||
106 | # We have a non-blank line after blank lines. Handle this. |
||
107 | (blankLines > 0) { |
||
108 | print lines |
||
109 | for (i = 0; i < blankLines; i++) { |
||
110 | print "" |
||
111 | } |
||
112 | |||
113 | lines = "" |
||
114 | blankLines = 0 |
||
115 | isFooter = 1 |
||
116 | footerComment = 0 |
||
117 | } |
||
118 | |||
119 | # Detect that the current block is not the footer |
||
120 | (footerComment == 0) && (!/^\[?[a-zA-Z0-9-]+:/ || /^[a-zA-Z0-9-]+:\/\//) { |
||
121 | isFooter = 0 |
||
122 | } |
||
123 | |||
124 | { |
||
125 | # We need this information about the current last comment line |
||
126 | if (footerComment == 2) { |
||
127 | footerComment = 0 |
||
128 | } |
||
129 | if (lines != "") { |
||
130 | lines = lines "\n"; |
||
131 | } |
||
132 | lines = lines $0 |
||
133 | } |
||
134 | |||
135 | # Footer handling: |
||
136 | # If the last block is considered a footer, splice in the Change-Id at the |
||
137 | # right place. |
||
138 | # Look for the right place to inject Change-Id by considering |
||
139 | # CHANGE_ID_AFTER. Keys listed in it (case insensitive) come first, |
||
140 | # then Change-Id, then everything else (eg. Signed-off-by:). |
||
141 | # |
||
142 | # Otherwise just print the last block, a new line and the Change-Id as a |
||
143 | # block of its own. |
||
144 | END { |
||
145 | unprinted = 1 |
||
146 | if (isFooter == 0) { |
||
147 | print lines "\n" |
||
148 | lines = "" |
||
149 | } |
||
150 | changeIdAfter = "^(" tolower("'"$CHANGE_ID_AFTER"'") "):" |
||
151 | numlines = split(lines, footer, "\n") |
||
152 | for (line = 1; line <= numlines; line++) { |
||
153 | if (unprinted && match(tolower(footer[line]), changeIdAfter) != 1) { |
||
154 | unprinted = 0 |
||
155 | print "Change-Id: I'"$id"'" |
||
156 | } |
||
157 | print footer[line] |
||
158 | } |
||
159 | if (unprinted) { |
||
160 | print "Change-Id: I'"$id"'" |
||
161 | } |
||
162 | }' "$MSG" > "$T" && mv "$T" "$MSG" || rm -f "$T" |
||
163 | } |
||
164 | _gen_ChangeIdInput() { |
||
165 | echo "tree `git write-tree`" |
||
166 | if parent=`git rev-parse "HEAD^0" 2>/dev/null` |
||
167 | then |
||
168 | echo "parent $parent" |
||
169 | fi |
||
170 | echo "author `git var GIT_AUTHOR_IDENT`" |
||
171 | echo "committer `git var GIT_COMMITTER_IDENT`" |
||
172 | echo |
||
173 | printf '%s' "$clean_message" |
||
174 | } |
||
175 | _gen_ChangeId() { |
||
176 | _gen_ChangeIdInput | |
||
177 | git hash-object -t commit --stdin |
||
178 | } |
||
179 | |||
180 | |||
181 | add_ChangeId |