| #!/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" | |
| } |