aboutsummaryrefslogtreecommitdiffstats
path: root/GRADUATED
blob: b8130c195f81d6e7fe0a5fb60ecf50f391367b19 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/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"
}