1848b8605Smrg#!/bin/sh 2848b8605Smrg 3848b8605Smrg# Script for generating a list of candidates for cherry-picking to a stable branch 4848b8605Smrg# 5848b8605Smrg# Usage examples: 6848b8605Smrg# 7848b8605Smrg# $ bin/get-pick-list.sh 8848b8605Smrg# $ bin/get-pick-list.sh > picklist 9848b8605Smrg# $ bin/get-pick-list.sh | tee picklist 10b8e80941Smrg# 11b8e80941Smrg# The output is as follows: 12b8e80941Smrg# [nomination_type] commit_sha commit summary 13b8e80941Smrg 14b8e80941Smrgis_stable_nomination() 15b8e80941Smrg{ 16b8e80941Smrg git show --pretty=medium --summary "$1" | grep -q -i -o "CC:.*mesa-stable" 17b8e80941Smrg} 18b8e80941Smrg 19b8e80941Smrgis_typod_nomination() 20b8e80941Smrg{ 21b8e80941Smrg git show --pretty=medium --summary "$1" | grep -q -i -o "CC:.*mesa-dev" 22b8e80941Smrg} 23b8e80941Smrg 24b8e80941Smrgfixes= 25b8e80941Smrg 26b8e80941Smrg# Helper to handle various mistypos of the fixes tag. 27b8e80941Smrg# The tag string itself is passed as argument and normalised within. 28b8e80941Smrg# 29b8e80941Smrg# Resulting string in the global variable "fixes" and contains entries 30b8e80941Smrg# in the form "fixes:$sha" 31b8e80941Smrgis_sha_nomination() 32b8e80941Smrg{ 33b8e80941Smrg fixes=`git show --pretty=medium -s $1 | tr -d "\n" | \ 34b8e80941Smrg sed -e 's/'"$2"'/\nfixes:/Ig' | \ 35b8e80941Smrg grep -Eo 'fixes:[a-f0-9]{8,40}'` 36b8e80941Smrg 37b8e80941Smrg fixes_count=`echo "$fixes" | grep "fixes:" | wc -l` 38b8e80941Smrg if test $fixes_count -eq 0; then 39b8e80941Smrg return 1 40b8e80941Smrg fi 41b8e80941Smrg 42b8e80941Smrg # Throw a warning for each invalid sha 43b8e80941Smrg while test $fixes_count -gt 0; do 44b8e80941Smrg # Treat only the current line 45b8e80941Smrg id=`echo "$fixes" | tail -n $fixes_count | head -n 1 | cut -d : -f 2` 46b8e80941Smrg fixes_count=$(($fixes_count-1)) 47b8e80941Smrg if ! git show $id >/dev/null 2>&1; then 48b8e80941Smrg echo WARNING: Commit $1 lists invalid sha $id 49b8e80941Smrg fi 50b8e80941Smrg done 51b8e80941Smrg 52b8e80941Smrg return 0 53b8e80941Smrg} 54b8e80941Smrg 55b8e80941Smrg# Checks if at least one of offending commits, listed in the global 56b8e80941Smrg# "fixes", is in branch. 57b8e80941Smrgsha_in_range() 58b8e80941Smrg{ 59b8e80941Smrg fixes_count=`echo "$fixes" | grep "fixes:" | wc -l` 60b8e80941Smrg while test $fixes_count -gt 0; do 61b8e80941Smrg # Treat only the current line 62b8e80941Smrg id=`echo "$fixes" | tail -n $fixes_count | head -n 1 | cut -d : -f 2` 63b8e80941Smrg fixes_count=$(($fixes_count-1)) 64b8e80941Smrg 65b8e80941Smrg # Be that cherry-picked ... 66b8e80941Smrg # ... or landed before the branchpoint. 67b8e80941Smrg if grep -q ^$id already_picked || 68b8e80941Smrg grep -q ^$id already_landed ; then 69b8e80941Smrg return 0 70b8e80941Smrg fi 71b8e80941Smrg done 72b8e80941Smrg return 1 73b8e80941Smrg} 74b8e80941Smrg 75b8e80941Smrgis_fixes_nomination() 76b8e80941Smrg{ 77b8e80941Smrg is_sha_nomination "$1" "fixes:[[:space:]]*" 78b8e80941Smrg if test $? -eq 0; then 79b8e80941Smrg return 0 80b8e80941Smrg fi 81b8e80941Smrg is_sha_nomination "$1" "fixes[[:space:]]\+" 82b8e80941Smrg} 83b8e80941Smrg 84b8e80941Smrgis_brokenby_nomination() 85b8e80941Smrg{ 86b8e80941Smrg is_sha_nomination "$1" "broken by" 87b8e80941Smrg} 88b8e80941Smrg 89b8e80941Smrgis_revert_nomination() 90b8e80941Smrg{ 91b8e80941Smrg is_sha_nomination "$1" "This reverts commit " 92b8e80941Smrg} 93b8e80941Smrg 94b8e80941Smrg# Use the last branchpoint as our limit for the search 95b8e80941Smrglatest_branchpoint=`git merge-base origin/master HEAD` 96b8e80941Smrg 97b8e80941Smrg# List all the commits between day 1 and the branch point... 98b8e80941Smrggit log --reverse --pretty=%H $latest_branchpoint > already_landed 99848b8605Smrg 100b8e80941Smrg# ... and the ones cherry-picked. 101b8e80941Smrggit log --reverse --pretty=medium --grep="cherry picked from commit" $latest_branchpoint..HEAD |\ 102848b8605Smrg grep "cherry picked from commit" |\ 103848b8605Smrg sed -e 's/^[[:space:]]*(cherry picked from commit[[:space:]]*//' -e 's/)//' > already_picked 104848b8605Smrg 105b8e80941Smrg# Grep for potential candidates 106b8e80941Smrggit log --reverse --pretty=%H -i --grep='^CC:.*mesa-stable\|^CC:.*mesa-dev\|\<fixes\>\|\<broken by\>\|This reverts commit' $latest_branchpoint..origin/master |\ 107848b8605Smrgwhile read sha 108848b8605Smrgdo 109848b8605Smrg # Check to see whether the patch is on the ignore list. 110b8e80941Smrg if test -f bin/.cherry-ignore; then 111848b8605Smrg if grep -q ^$sha bin/.cherry-ignore ; then 112848b8605Smrg continue 113848b8605Smrg fi 114848b8605Smrg fi 115848b8605Smrg 116848b8605Smrg # Check to see if it has already been picked over. 117848b8605Smrg if grep -q ^$sha already_picked ; then 118848b8605Smrg continue 119848b8605Smrg fi 120848b8605Smrg 121b8e80941Smrg if is_fixes_nomination "$sha"; then 122b8e80941Smrg tag=fixes 123b8e80941Smrg elif is_brokenby_nomination "$sha"; then 124b8e80941Smrg tag=brokenby 125b8e80941Smrg elif is_revert_nomination "$sha"; then 126b8e80941Smrg tag=revert 127b8e80941Smrg elif is_stable_nomination "$sha"; then 128b8e80941Smrg tag=stable 129b8e80941Smrg elif is_typod_nomination "$sha"; then 130b8e80941Smrg tag=typod 131b8e80941Smrg else 132b8e80941Smrg continue 133b8e80941Smrg fi 134b8e80941Smrg 135b8e80941Smrg case "$tag" in 136b8e80941Smrg fixes | brokenby | revert ) 137b8e80941Smrg if ! sha_in_range; then 138b8e80941Smrg continue 139b8e80941Smrg fi 140b8e80941Smrg ;; 141b8e80941Smrg * ) 142b8e80941Smrg ;; 143b8e80941Smrg esac 144b8e80941Smrg 145b8e80941Smrg printf "[ %8s ] " "$tag" 146b8e80941Smrg git --no-pager show --no-patch --oneline $sha 147848b8605Smrgdone 148848b8605Smrg 149848b8605Smrgrm -f already_picked 150b8e80941Smrgrm -f already_landed 151