1#! /bin/sh -e 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright 2016 6WIND S.A. 4 5print_usage () 6{ 7 echo "usage: $(basename $0) [-h] <git_range>" 8} 9 10print_help () 11{ 12 print_usage 13 cat <<- END_OF_HELP 14 15 Find fixes to backport on previous versions. 16 It looks for the word "fix" in the headline or a tag "Fixes" or "Reverts". 17 The oldest bug origin is printed as well as partially fixed versions. 18 END_OF_HELP 19} 20 21usage_error () # <message> 22{ 23 echo "$*" >&2 24 print_usage >&2 25 exit 1 26} 27 28while getopts h ARG ; do 29 case $ARG in 30 h ) print_help ; exit 0 ;; 31 ? ) print_usage >&2 ; exit 1 ;; 32 esac 33done 34shift $(($OPTIND - 1)) 35[ $# -ge 1 ] || usage_error 'range argument required' 36range="$*" 37 38# get major release version of a commit 39commit_version () # <hash> 40{ 41 # use current branch as history reference 42 local refbranch=$(git rev-parse --abbrev-ref HEAD) 43 local tag=$( (git tag -l --contains $1 --merged $refbranch 2>&- || 44 # tag --merged option has been introduced in git 2.7.0 45 # below is a fallback in case of old git version 46 for t in $(git tag -l --contains $1) ; do 47 git branch $refbranch --contains $t | 48 sed "s,.\+,$t," 49 done) | 50 head -n1) 51 if [ -z "$tag" ] ; then 52 # before -rc1 tag of release in progress 53 make showversion | cut -d'.' -f-2 54 else 55 echo $tag | sed 's,^v,,' | sed 's,-rc.*,,' 56 fi 57} 58 59# get bug origin hashes of a fix 60origin_filter () # <hash> 61{ 62 git log --format='%b' -1 $1 | 63 sed -n 's,^ *\([Ff]ixes\|[Rr]everts\): *\([0-9a-f]*\).*,\2,p' 64} 65 66# get oldest major release version of bug origins 67origin_version () # <origin_hash> ... 68{ 69 for origin in $* ; do 70 # check hash is valid 71 git rev-parse -q --verify $1 >&- || continue 72 # get version of this bug origin 73 local origver=$(commit_version $origin) 74 local roothashes="$(origin_filter $origin)" 75 if [ -n "$roothashes" ] ; then 76 # look chained fix of fix recursively 77 local rootver="$(origin_version $roothashes)" 78 [ -n "$rootver" ] || continue 79 echo "$rootver (partially fixed in $origver)" 80 else 81 echo "$origver" 82 fi 83 # filter the oldest origin 84 done | sort -uV | head -n1 85} 86 87# print a marker for stable tag presence 88stable_tag () # <hash> 89{ 90 if git log --format='%b' -1 $1 | grep -qi '^Cc: *stable@dpdk.org' ; then 91 echo 'S' 92 else 93 echo '-' 94 fi 95} 96 97git log --oneline --reverse $range | 98while read id headline ; do 99 origins=$(origin_filter $id) 100 stable=$(stable_tag $id) 101 [ "$stable" = "S" ] || [ -n "$origins" ] || echo "$headline" | grep -q fix || continue 102 version=$(commit_version $id) 103 if [ -n "$origins" ] ; then 104 origver="$(origin_version $origins)" 105 [ -n "$origver" ] || continue 106 # ignore fix of bug introduced in the same release 107 ! echo "$origver" | grep -q "^$version" || continue 108 else 109 origver='N/A' 110 fi 111 printf '%s %7s %s %s (%s)\n' $version $id $stable "$headline" "$origver" 112done 113