#!/bin/sh base= while : do case "$1" in --base=*) base=${1#*=} ;; -*) echo >&2 "Eh? $1" exit 1 ;; *) break ;; esac shift done if test -z "$base" then describe=$(git describe "master") base=$(expr "$describe" : '\(.*\)-\([0-9]*\)-g[0-9a-f]*$') || base="$describe" git rev-parse --verify "$base^0" >/dev/null 2>/dev/null || { echo >&2 "Eh? where is your base?" exit 1 } fi topics= leftover= dothis= LF=' ' defer () { leftover="$leftover$1$LF" } dothis () { dothis="$1$LF$LF$dothis" } one_topic () { topic="$1" tip="$2" date="$3" case " $topics" in *" $topic "*) return ;; esac topics="$topics$topic " mergeable=no ready=no label= maint_count=$(git rev-list "maint..$tip" | wc -l) if test "$maint_count" = 0 then return ;# already merged fi master_count=$(git rev-list "$base..$tip" | wc -l) test $master_count = $maint_count && mergeable=yes if current=$(git rev-parse --verify -q "$topic^0") && test "$current" = "$tip" then ready=yes label="$topic" elif test -z "$current" then ready=yes label="$tip" fi case "$mergeable,$ready" in no,*) defer "# $topic: not mergeable ($master_count vs $maint_count)" ;; yes,no) topic_count=$(git rev-list "$base..$current" | wc -l) defer "# $topic: not ready ($master_count vs $topic_count)" ;; yes,yes) insn="$label # $master_count ($date)" insn="$insn$LF$(git log --oneline "maint..$tip" | sed -e "s/^/# /")" dothis "$insn" ;; esac } git log --first-parent --min-parents=2 --max-parents=2 \ --format='%ci %H %P %s' "$base..master" | { while read date time zone commit parent tip subject do topic=$(expr "$subject" : "Merge branch '\(.*\)'$") || { echo >&2 "Cannot parse $commit ($subject)" continue } one_topic "$topic" "$tip" "$date" done echo "$leftover" echo "$dothis" }