#!/bin/sh base= ignore_file= while : do case "$1" in --base=*) base=${1#*=} ;; --ignore=*) ignore_file=${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=' ' ignores= if test -f "$ignore_file" then while read ignore rest do test -n "$ignore" && if ignore=$(git rev-parse -q --verify $ignore) then : elif ignore=$(expr "$rest" : '.* \([0-9a-f]\{40\}\)$') then : else continue fi ignores="$ignores$ignore " done <"$ignore_file" fi defer () { leftover="$leftover$1$LF" } dothis () { dothis="$1$LF$LF$dothis" } one_topic () { topic="$2" tip="$3" date="$4" merged="$1" case " $topics" in *" $topic "*) return ;; esac topics="$topics$topic " contam_count=$(git rev-list "maint..$tip" | grep -F "$merges_to_master" | wc -l) if test "$contam_count" != 0 then echo "**** forked from master $topic ****" return fi maint_count=$(git rev-list "maint..$tip" | wc -l) if test "$maint_count" = 0 then echo "**** already merged $topic ****" return ;# already merged fi ready=no label= master_count=$(git rev-list "$base..$tip" | wc -l) if test $maint_count -le $master_count then mergeable=yes else mergeable=no fi 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,*) comment="# $topic: not mergeable ($master_count vs $maint_count)" comment="$comment$LF# $merged" defer "$comment" ;; yes,no) topic_count=$(git rev-list "$base..$current" | wc -l) comment="# $topic: not ready ($master_count vs $topic_count)" comment="$comment$LF# $merged" defer "$comment" ;; yes,yes) insn="$label" if test $maint_count = $master_count then insn="$insn # $master_count ($date) $merged" else insn="$insn # $maint_count/$master_count ($date) $merged" fi insn="$insn$LF$(git log --oneline "maint..$tip" | sed -e "s/^/# /")" dothis "$insn" ;; esac } merges_to_master="$(git rev-list --merges $base..master)" 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 case " $ignores" in *" $commit "*) continue ;; esac topic=$(expr "$subject" : "Merge branch '\(.*\)'$") || { defer "# ignoring $commit ($subject)" continue } one_topic "$commit" "$topic" "$tip" "$date" done echo "$leftover" echo "$dothis" }