summaryrefslogtreecommitdiff
path: root/bin/get-pick-list.sh
blob: 8fa4f438771680f72c0faeb64f3e6bb281c8fdc6 (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
146
147
148
149
150
#!/bin/sh

# Script for generating a list of candidates for cherry-picking to a stable branch
#
# Usage examples:
#
# $ bin/get-pick-list.sh
# $ bin/get-pick-list.sh > picklist
# $ bin/get-pick-list.sh | tee picklist
#
# The output is as follows:
# [nomination_type] commit_sha commit summary

is_stable_nomination()
{
	git show --pretty=medium --summary "$1" | grep -q -i -o "CC:.*mesa-stable"
}

is_typod_nomination()
{
	git show --pretty=medium --summary "$1" | grep -q -i -o "CC:.*mesa-dev"
}

fixes=

# Helper to handle various mistypos of the fixes tag.
# The tag string itself is passed as argument and normalised within.
#
# Resulting string in the global variable "fixes" and contains entries
# in the form "fixes:$sha"
is_sha_nomination()
{
	fixes=`git show --pretty=medium -s $1 | tr -d "\n" | \
		sed -e 's/'"$2"'/\nfixes:/Ig' | \
		grep -Eo 'fixes:[a-f0-9]{8,40}'`

	fixes_count=`echo "$fixes" | grep "fixes:" | wc -l`
	if test $fixes_count -eq 0; then
		return 1
	fi

	# Throw a warning for each invalid sha
	while test $fixes_count -gt 0; do
		# Treat only the current line
		id=`echo "$fixes" | tail -n $fixes_count | head -n 1 | cut -d : -f 2`
		fixes_count=$(($fixes_count-1))
		if ! git show $id >/dev/null 2>&1; then
			echo WARNING: Commit $1 lists invalid sha $id
		fi
	done

	return 0
}

# Checks if at least one of offending commits, listed in the global
# "fixes", is in branch.
sha_in_range()
{
	fixes_count=`echo "$fixes" | grep "fixes:" | wc -l`
	while test $fixes_count -gt 0; do
		# Treat only the current line
		id=`echo "$fixes" | tail -n $fixes_count | head -n 1 | cut -d : -f 2`
		fixes_count=$(($fixes_count-1))

		# Be that cherry-picked ...
		# ... or landed before the branchpoint.
		if grep -q ^$id already_picked ||
		   grep -q ^$id already_landed ; then
			return 0
		fi
	done
	return 1
}

is_fixes_nomination()
{
	is_sha_nomination "$1" "fixes:[[:space:]]*"
	if test $? -eq 0; then
		return 0
	fi
	is_sha_nomination "$1" "fixes[[:space:]]\+"
}

is_brokenby_nomination()
{
	is_sha_nomination "$1" "broken by"
}

is_revert_nomination()
{
	is_sha_nomination "$1" "This reverts commit "
}

# Use the last branchpoint as our limit for the search
latest_branchpoint=`git merge-base origin/master HEAD`

# List all the commits between day 1 and the branch point...
git log --reverse --pretty=%H $latest_branchpoint > already_landed

# ... and the ones cherry-picked.
git log --reverse --pretty=medium --grep="cherry picked from commit" $latest_branchpoint..HEAD |\
	grep "cherry picked from commit" |\
	sed -e 's/^[[:space:]]*(cherry picked from commit[[:space:]]*//' -e 's/)//' > already_picked

# Grep for potential candidates
git log --reverse --pretty=%H -i --grep='^CC:.*mesa-stable\|^CC:.*mesa-dev\|\<fixes\>\|\<broken by\>\|This reverts commit' $latest_branchpoint..origin/master |\
while read sha
do
	# Check to see whether the patch is on the ignore list.
	if test -f bin/.cherry-ignore; then
		if grep -q ^$sha bin/.cherry-ignore ; then
			continue
		fi
	fi

	# Check to see if it has already been picked over.
	if grep -q ^$sha already_picked ; then
		continue
	fi

	if is_fixes_nomination "$sha"; then
		tag=fixes
	elif is_brokenby_nomination "$sha"; then
		tag=brokenby
	elif is_revert_nomination "$sha"; then
		tag=revert
	elif is_stable_nomination "$sha"; then
		tag=stable
	elif is_typod_nomination "$sha"; then
		tag=typod
	else
		continue
	fi

	case "$tag" in
	fixes | brokenby | revert )
		if ! sha_in_range; then
			continue
		fi
		;;
	* )
		;;
	esac

	printf "[ %8s ] " "$tag"
	git --no-pager show --no-patch --oneline $sha
done

rm -f already_picked
rm -f already_landed