From: Junio C Hamano Date: Fri, 21 Aug 2009 01:21:20 +0000 (-0700) Subject: A new implementation of What's cooking script X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eac569bc59d3b39fffe4597ed8bfc3f9a1b37418;p=thirdparty%2Fgit.git A new implementation of What's cooking script --- diff --git a/cook.sh b/cook.sh new file mode 100755 index 0000000000..563cac9c59 --- /dev/null +++ b/cook.sh @@ -0,0 +1,325 @@ +#!/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" <$tmp.template.toc"; + open O, ">$tmp.template.0"; + + while () { + 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"