A new implementation of What's cooking script
Junio C Hamano committed
Aug 20, 2009 at 18:21 UTC
eac569bc59d3b39fffe4597ed8bfc3f9a1b37418
1 file changed
+325
cook.sh
new
+325
@@ -0,0 +1,325 @@
1
+#!/bin/sh
2
+
3
+LANG=C LC_ALL=C GIT_PAGER=cat
4
+export LANG LC_ALL GIT_PAGER
5
+
6
+tmp=/var/tmp/cook.$$
7
+trap 'rm -f "$tmp".*' 0
8
+
9
+git branch --merged "master" | sed -n -e 's/^..//' -e '/\//p' >"$tmp.in.master"
10
+git branch --merged "pu" | sed -n -e 's/^..//' -e '/\//p' >"$tmp.in.pu"
11
+{
12
+ comm -13 "$tmp.in.master" "$tmp.in.pu"
13
+ git branch --no-merged pu |
14
+ sed -n -e 's/^..//' -e '/\//p'
15
+} >"$tmp.branches"
16
+
17
+git log --first-parent --format="%H %ci" master..next |
18
+sed -e 's/ [0-2][0-9]:[0-6][0-9]:[0-6][0-9] [-+][0-2][0-9][0-6][0-9]$//' >"$tmp.next"
19
+git rev-list master..pu >"$tmp.commits.in.pu"
20
+
21
+format_branch () {
22
+ # branch=$1 others=$2
23
+ git rev-list --no-merges --topo-order "master..$1" --not $2 >"$tmp.list"
24
+ count=$(wc -l <"$tmp.list" | tr -d ' ')
25
+ label="* $1 ($(git show -s --format="%ai" $1 | sed -e 's/ .*//')) $count commit"
26
+ test "$count" = 1 || label="${label}s"
27
+
28
+ count=$(git rev-list "master..$1" | wc -l)
29
+ mcount=$(git rev-list "maint..$1" | wc -l)
30
+ if test $mcount = $count
31
+ then
32
+ label="$label."
33
+ fi
34
+
35
+ echo "$label"
36
+ lasttimelabel=
37
+ lastfoundmerge=
38
+ while read commit
39
+ do
40
+ merged= merged_with=
41
+ while read merge at
42
+ do
43
+ if test -n "$lastfoundmerge"
44
+ then
45
+ if test "$lastfoundmerge" = "$merge"
46
+ then
47
+ lastfoundmerge=
48
+ else
49
+ continue
50
+ fi
51
+ fi
52
+ mb=$(git merge-base $merge $commit)
53
+ if test "$mb" = "$commit"
54
+ then
55
+ merged=$at merged_with=$merge
56
+ else
57
+ break
58
+ fi
59
+ done <"$tmp.next"
60
+
61
+ lastfoundmerge=$merged_with
62
+ thistimelabel=
63
+ if test -n "$merged"
64
+ then
65
+ thistimelabel=$merged
66
+ commitlabel="+"
67
+ elif grep "$commit" "$tmp.commits.in.pu" >/dev/null
68
+ then
69
+ commitlabel="-"
70
+ else
71
+ commitlabel="."
72
+ fi
73
+ if test "$lasttimelabel" != "$thistimelabel"
74
+ then
75
+ with=$(git rev-parse --short $merged_with)
76
+ echo " (merged to 'next' on $thistimelabel at $with)"
77
+ lasttimelabel=$thistimelabel
78
+ fi
79
+ git show -s --format=" $commitlabel %s" $commit
80
+ done <"$tmp.list"
81
+}
82
+
83
+add_desc () {
84
+ kind=$1
85
+ shift
86
+ test -z "$description" || description="$description;"
87
+ others=
88
+ while :
89
+ do
90
+ other=$1
91
+ shift
92
+ case "$#,$others" in
93
+ 0,)
94
+ others="$other"
95
+ break ;;
96
+ 0,?*)
97
+ others="$others and $other"
98
+ break ;;
99
+ *,)
100
+ others="$other"
101
+ ;;
102
+ *,?*)
103
+ others="$others, $other"
104
+ ;;
105
+ esac
106
+ done
107
+ description="$description $kind $others"
108
+}
109
+
110
+while read b
111
+do
112
+ git rev-list --no-merges "master..$b"
113
+done <"$tmp.branches" | sort | uniq -d >"$tmp.shared"
114
+
115
+while read shared
116
+do
117
+ b=$(git branch --contains "$shared" | sed -n -e 's/^..//' -e '/\//p')
118
+ echo "" $b ""
119
+done <"$tmp.shared" | sort -u >"$tmp.related"
120
+
121
+serial=1
122
+while read b
123
+do
124
+ related=$(grep " $b " "$tmp.related" | tr ' ' '\012' | sort -u | sed -e '/^$/d')
125
+
126
+ based_on=
127
+ used_by=
128
+ forks=
129
+ same_as=
130
+ if test -n "$related"
131
+ then
132
+ for r in $related
133
+ do
134
+ test "$b" = "$r" && continue
135
+ based=$(git rev-list --no-merges $b..$r | wc -l | tr -d ' ')
136
+ bases=$(git rev-list --no-merges $r..$b | wc -l | tr -d ' ')
137
+ case "$based,$bases" in
138
+ 0,0)
139
+ same_as="$same_as$r "
140
+ ;;
141
+ 0,*)
142
+ based_on="$based_on$r "
143
+ ;;
144
+ *,0)
145
+ used_by="$used_by$r "
146
+ ;;
147
+ *,*)
148
+ forks="$forks$r "
149
+ ;;
150
+ esac
151
+ done
152
+ fi
153
+
154
+ {
155
+ format_branch "$b" "$based_on"
156
+
157
+ description=
158
+ test -z "$same_as" || add_desc 'is same as' $same_as
159
+ test -z "$based_on" || add_desc 'uses' $based_on
160
+ test -z "$used_by" || add_desc 'is used by' $used_by
161
+ test -z "$forks" || add_desc 'is related to' $forks
162
+
163
+ test -z "$description" ||
164
+ echo " (this branch$description.)"
165
+ } >"$tmp.output.$serial"
166
+ echo "$b $serial"
167
+ serial=$(( $serial + 1 ))
168
+done <"$tmp.branches" >"$tmp.output.toc"
169
+
170
+eval $(date +"monthname=%b month=%m year=%Y date=%d dow=%a")
171
+lead="whats/cooking/$year/$month"
172
+issue=$(
173
+ cd Meta &&
174
+ git ls-tree -r --name-only HEAD "$lead" | tail -n 1
175
+)
176
+if test -n "$issue"
177
+then
178
+ issue=$( expr "$issue" : '.*/0*\([1-9][0-9]*\)\.txt$' )
179
+ issue=$(( $issue + 1 ))
180
+else
181
+ issue=1
182
+fi
183
+issue=$( printf "%02d" $issue )
184
+mkdir -p "Meta/$lead"
185
+
186
+last=$(
187
+ cd Meta &&
188
+ git ls-tree -r --name-only HEAD "whats/cooking" | tail -n 1
189
+)
190
+
191
+master_at=$(git rev-parse --verify refs/heads/master)
192
+next_at=$(git rev-parse --verify refs/heads/next)
193
+cat >"$tmp.output.0" <<EOF
194
+To: git@vger.kernel.org
195
+Subject: What's cooking in git.git ($monthname $year, #$issue; $dow, $date)
196
+X-master-at: $master_at
197
+X-next-at: $next_at
198
+
199
+What's cooking in git.git ($monthname $year, #$issue; $dow, $date)
200
+--------------------------------------------------
201
+
202
+Here are the topics that have been cooking. Commits prefixed with '-' are
203
+only in 'pu' while commits prefixed with '+' are in 'next'. The ones
204
+marked with '.' do not appear in any of the branches, but I am still
205
+holding onto them.
206
+
207
+EOF
208
+
209
+if test -z "$NO_TEMPLATE" && test -f "Meta/$last"
210
+then
211
+ template="Meta/$last"
212
+else
213
+ template=/dev/null
214
+fi
215
+perl -w -e '
216
+ my $section = undef;
217
+ my $serial = 1;
218
+ my $branch = "b:l:u:r:b";
219
+ my $tmp = $ARGV[0];
220
+ my $last_empty = undef;
221
+
222
+ open TOC, ">$tmp.template.toc";
223
+ open O, ">$tmp.template.0";
224
+
225
+ while (<STDIN>) {
226
+ if (defined $section && /^-{20,}/) {
227
+ $_ = "\n";
228
+ }
229
+ if (/^$/) {
230
+ $last_empty = 1;
231
+ next;
232
+ }
233
+ if (/\[(.*)\]\s*$/) {
234
+ $section = $1;
235
+ $branch = undef;
236
+ next;
237
+ }
238
+ if (defined $section && /^\* (\S+) /) {
239
+ $branch = $1;
240
+ $last_empty = 0;
241
+ open O, ">$tmp.template.$serial";
242
+ print TOC "$branch $serial $section\n";
243
+ $serial++;
244
+ }
245
+ if (defined $branch) {
246
+ print O "\n" if ($last_empty);
247
+ $last_empty = 0;
248
+ print O "$_";
249
+ }
250
+ }
251
+' <"$template" "$tmp"
252
+
253
+# Assemble them all
254
+
255
+if test -z "$TO_STDOUT"
256
+then
257
+ exec >"Meta/$lead/$issue.txt"
258
+fi
259
+
260
+if test -s "$tmp.template.0"
261
+then
262
+ sed -e '/^---------------*/q' <"$tmp.output.0"
263
+ sed -e '1,/^---------------*/d' <"$tmp.template.0"
264
+else
265
+ cat "$tmp.output.0"
266
+fi | sed -e '$d'
267
+
268
+current='--------------------------------------------------
269
+[New Topics]
270
+'
271
+while read branch serial
272
+do
273
+ grep "^$branch " "$tmp.template.toc" >/dev/null && continue
274
+ if test -n "$current"
275
+ then
276
+ echo "$current"
277
+ current=
278
+ else
279
+ echo
280
+ fi
281
+ cat "$tmp.output.$serial"
282
+done <"$tmp.output.toc"
283
+
284
+current='--------------------------------------------------
285
+[Graduated to "master"]
286
+'
287
+while read branch oldserial section
288
+do
289
+ test "$section" = 'Graduated to "master"' && continue
290
+ tip=$(git rev-parse --quiet --verify "refs/heads/$branch")
291
+ mb=$(git merge-base master $tip)
292
+ test "$mb" = "$tip" || continue
293
+ if test -n "$current"
294
+ then
295
+ echo "$current"
296
+ current=
297
+ else
298
+ echo
299
+ fi
300
+ cat "$tmp.template.$oldserial"
301
+done <"$tmp.template.toc"
302
+
303
+current=
304
+while read branch oldserial section
305
+do
306
+ found=$(grep "^$branch " "$tmp.output.toc") || continue
307
+ newserial=$(expr "$found" : '[^ ]* \(.*\)')
308
+ if test "$section" = "New Topics"
309
+ then
310
+ section="Old New Topics"
311
+ fi
312
+ if test "$current" != "$section"
313
+ then
314
+ current=$section
315
+ echo "--------------------------------------------------
316
+[$section]
317
+"
318
+ else
319
+ echo
320
+ fi
321
+ cat "$tmp.output.$newserial"
322
+ echo "<<"
323
+ cat "$tmp.template.$oldserial"
324
+ echo ">>"
325
+done <"$tmp.template.toc"