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