You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
325 lines
6.8 KiB
325 lines
6.8 KiB
#!/bin/sh |
|
|
|
LANG=C LC_ALL=C GIT_PAGER=cat |
|
export LANG LC_ALL GIT_PAGER |
|
|
|
tmp=/var/tmp/cook.$$ |
|
trap 'rm -f "$tmp".*' 0 |
|
|
|
git branch --merged "master" | sed -n -e 's/^..//' -e '/\//p' >"$tmp.in.master" |
|
git branch --merged "pu" | sed -n -e 's/^..//' -e '/\//p' >"$tmp.in.pu" |
|
{ |
|
comm -13 "$tmp.in.master" "$tmp.in.pu" |
|
git branch --no-merged pu | |
|
sed -n -e 's/^..//' -e '/\//p' |
|
} >"$tmp.branches" |
|
|
|
git log --first-parent --format="%H %ci" master..next | |
|
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" |
|
git rev-list master..pu >"$tmp.commits.in.pu" |
|
|
|
format_branch () { |
|
# branch=$1 others=$2 |
|
git rev-list --no-merges --topo-order "master..$1" --not $2 >"$tmp.list" |
|
count=$(wc -l <"$tmp.list" | tr -d ' ') |
|
label="* $1 ($(git show -s --format="%ai" $1 | sed -e 's/ .*//')) $count commit" |
|
test "$count" = 1 || label="${label}s" |
|
|
|
count=$(git rev-list "master..$1" | wc -l) |
|
mcount=$(git rev-list "maint..$1" | wc -l) |
|
if test $mcount = $count |
|
then |
|
label="$label." |
|
fi |
|
|
|
echo "$label" |
|
lasttimelabel= |
|
lastfoundmerge= |
|
while read commit |
|
do |
|
merged= merged_with= |
|
while read merge at |
|
do |
|
if test -n "$lastfoundmerge" |
|
then |
|
if test "$lastfoundmerge" = "$merge" |
|
then |
|
lastfoundmerge= |
|
else |
|
continue |
|
fi |
|
fi |
|
mb=$(git merge-base $merge $commit) |
|
if test "$mb" = "$commit" |
|
then |
|
merged=$at merged_with=$merge |
|
else |
|
break |
|
fi |
|
done <"$tmp.next" |
|
|
|
lastfoundmerge=$merged_with |
|
thistimelabel= |
|
if test -n "$merged" |
|
then |
|
thistimelabel=$merged |
|
commitlabel="+" |
|
elif grep "$commit" "$tmp.commits.in.pu" >/dev/null |
|
then |
|
commitlabel="-" |
|
else |
|
commitlabel="." |
|
fi |
|
if test "$lasttimelabel" != "$thistimelabel" |
|
then |
|
with=$(git rev-parse --short $merged_with) |
|
echo " (merged to 'next' on $thistimelabel at $with)" |
|
lasttimelabel=$thistimelabel |
|
fi |
|
git show -s --format=" $commitlabel %s" $commit |
|
done <"$tmp.list" |
|
} |
|
|
|
add_desc () { |
|
kind=$1 |
|
shift |
|
test -z "$description" || description="$description;" |
|
others= |
|
while : |
|
do |
|
other=$1 |
|
shift |
|
case "$#,$others" in |
|
0,) |
|
others="$other" |
|
break ;; |
|
0,?*) |
|
others="$others and $other" |
|
break ;; |
|
*,) |
|
others="$other" |
|
;; |
|
*,?*) |
|
others="$others, $other" |
|
;; |
|
esac |
|
done |
|
description="$description $kind $others" |
|
} |
|
|
|
while read b |
|
do |
|
git rev-list --no-merges "master..$b" |
|
done <"$tmp.branches" | sort | uniq -d >"$tmp.shared" |
|
|
|
while read shared |
|
do |
|
b=$(git branch --contains "$shared" | sed -n -e 's/^..//' -e '/\//p') |
|
echo "" $b "" |
|
done <"$tmp.shared" | sort -u >"$tmp.related" |
|
|
|
serial=1 |
|
while read b |
|
do |
|
related=$(grep " $b " "$tmp.related" | tr ' ' '\012' | sort -u | sed -e '/^$/d') |
|
|
|
based_on= |
|
used_by= |
|
forks= |
|
same_as= |
|
if test -n "$related" |
|
then |
|
for r in $related |
|
do |
|
test "$b" = "$r" && continue |
|
based=$(git rev-list --no-merges $b..$r | wc -l | tr -d ' ') |
|
bases=$(git rev-list --no-merges $r..$b | wc -l | tr -d ' ') |
|
case "$based,$bases" in |
|
0,0) |
|
same_as="$same_as$r " |
|
;; |
|
0,*) |
|
based_on="$based_on$r " |
|
;; |
|
*,0) |
|
used_by="$used_by$r " |
|
;; |
|
*,*) |
|
forks="$forks$r " |
|
;; |
|
esac |
|
done |
|
fi |
|
|
|
{ |
|
format_branch "$b" "$based_on" |
|
|
|
description= |
|
test -z "$same_as" || add_desc 'is same as' $same_as |
|
test -z "$based_on" || add_desc 'uses' $based_on |
|
test -z "$used_by" || add_desc 'is used by' $used_by |
|
test -z "$forks" || add_desc 'is related to' $forks |
|
|
|
test -z "$description" || |
|
echo " (this branch$description.)" |
|
} >"$tmp.output.$serial" |
|
echo "$b $serial" |
|
serial=$(( $serial + 1 )) |
|
done <"$tmp.branches" >"$tmp.output.toc" |
|
|
|
eval $(date +"monthname=%b month=%m year=%Y date=%d dow=%a") |
|
lead="whats/cooking/$year/$month" |
|
issue=$( |
|
cd Meta && |
|
git ls-tree -r --name-only HEAD "$lead" | tail -n 1 |
|
) |
|
if test -n "$issue" |
|
then |
|
issue=$( expr "$issue" : '.*/0*\([1-9][0-9]*\)\.txt$' ) |
|
issue=$(( $issue + 1 )) |
|
else |
|
issue=1 |
|
fi |
|
issue=$( printf "%02d" $issue ) |
|
mkdir -p "Meta/$lead" |
|
|
|
last=$( |
|
cd Meta && |
|
git ls-tree -r --name-only HEAD "whats/cooking" | tail -n 1 |
|
) |
|
|
|
master_at=$(git rev-parse --verify refs/heads/master) |
|
next_at=$(git rev-parse --verify refs/heads/next) |
|
cat >"$tmp.output.0" <<EOF |
|
To: git@vger.kernel.org |
|
Subject: What's cooking in git.git ($monthname $year, #$issue; $dow, $date) |
|
X-master-at: $master_at |
|
X-next-at: $next_at |
|
|
|
What's cooking in git.git ($monthname $year, #$issue; $dow, $date) |
|
-------------------------------------------------- |
|
|
|
Here are the topics that have been cooking. Commits prefixed with '-' are |
|
only in 'pu' while commits prefixed with '+' are in 'next'. The ones |
|
marked with '.' do not appear in any of the branches, but I am still |
|
holding onto them. |
|
|
|
EOF |
|
|
|
if test -z "$NO_TEMPLATE" && test -f "Meta/$last" |
|
then |
|
template="Meta/$last" |
|
else |
|
template=/dev/null |
|
fi |
|
perl -w -e ' |
|
my $section = undef; |
|
my $serial = 1; |
|
my $branch = "b:l:u:r:b"; |
|
my $tmp = $ARGV[0]; |
|
my $last_empty = undef; |
|
|
|
open TOC, ">$tmp.template.toc"; |
|
open O, ">$tmp.template.0"; |
|
|
|
while (<STDIN>) { |
|
if (defined $section && /^-{20,}/) { |
|
$_ = "\n"; |
|
} |
|
if (/^$/) { |
|
$last_empty = 1; |
|
next; |
|
} |
|
if (/\[(.*)\]\s*$/) { |
|
$section = $1; |
|
$branch = undef; |
|
next; |
|
} |
|
if (defined $section && /^\* (\S+) /) { |
|
$branch = $1; |
|
$last_empty = 0; |
|
open O, ">$tmp.template.$serial"; |
|
print TOC "$branch $serial $section\n"; |
|
$serial++; |
|
} |
|
if (defined $branch) { |
|
print O "\n" if ($last_empty); |
|
$last_empty = 0; |
|
print O "$_"; |
|
} |
|
} |
|
' <"$template" "$tmp" |
|
|
|
# Assemble them all |
|
|
|
if test -z "$TO_STDOUT" |
|
then |
|
exec >"Meta/$lead/$issue.txt" |
|
fi |
|
|
|
if test -s "$tmp.template.0" |
|
then |
|
sed -e '/^---------------*/q' <"$tmp.output.0" |
|
sed -e '1,/^---------------*/d' <"$tmp.template.0" |
|
else |
|
cat "$tmp.output.0" |
|
fi | sed -e '$d' |
|
|
|
current='-------------------------------------------------- |
|
[New Topics] |
|
' |
|
while read branch serial |
|
do |
|
grep "^$branch " "$tmp.template.toc" >/dev/null && continue |
|
if test -n "$current" |
|
then |
|
echo "$current" |
|
current= |
|
else |
|
echo |
|
fi |
|
cat "$tmp.output.$serial" |
|
done <"$tmp.output.toc" |
|
|
|
current='-------------------------------------------------- |
|
[Graduated to "master"] |
|
' |
|
while read branch oldserial section |
|
do |
|
test "$section" = 'Graduated to "master"' && continue |
|
tip=$(git rev-parse --quiet --verify "refs/heads/$branch") |
|
mb=$(git merge-base master $tip) |
|
test "$mb" = "$tip" || continue |
|
if test -n "$current" |
|
then |
|
echo "$current" |
|
current= |
|
else |
|
echo |
|
fi |
|
cat "$tmp.template.$oldserial" |
|
done <"$tmp.template.toc" |
|
|
|
current= |
|
while read branch oldserial section |
|
do |
|
found=$(grep "^$branch " "$tmp.output.toc") || continue |
|
newserial=$(expr "$found" : '[^ ]* \(.*\)') |
|
if test "$section" = "New Topics" |
|
then |
|
section="Old New Topics" |
|
fi |
|
if test "$current" != "$section" |
|
then |
|
current=$section |
|
echo "-------------------------------------------------- |
|
[$section] |
|
" |
|
else |
|
echo |
|
fi |
|
cat "$tmp.output.$newserial" |
|
echo "<<" |
|
cat "$tmp.template.$oldserial" |
|
echo ">>" |
|
done <"$tmp.template.toc"
|
|
|