xref: /dpdk/devtools/git-log-fixes.sh (revision e2e4775cc7a0699a66283ed6ddb0c2a51daae1ef)
19a98f50eSThomas Monjalon#! /bin/sh -e
2f83a3d3fSOlivier Matz# SPDX-License-Identifier: BSD-3-Clause
39a98f50eSThomas Monjalon# Copyright 2016 6WIND S.A.
49a98f50eSThomas Monjalon
59a98f50eSThomas Monjalonprint_usage ()
69a98f50eSThomas Monjalon{
79a98f50eSThomas Monjalon	echo "usage: $(basename $0) [-h] <git_range>"
89a98f50eSThomas Monjalon}
99a98f50eSThomas Monjalon
109a98f50eSThomas Monjalonprint_help ()
119a98f50eSThomas Monjalon{
129a98f50eSThomas Monjalon	print_usage
139a98f50eSThomas Monjalon	cat <<- END_OF_HELP
149a98f50eSThomas Monjalon
159a98f50eSThomas Monjalon	Find fixes to backport on previous versions.
1678bdab09SChristian Ehrhardt	It looks for a tag "Fixes" or for "Cc: stable@dpdk.org".
179a98f50eSThomas Monjalon	The oldest bug origin is printed as well as partially fixed versions.
189a98f50eSThomas Monjalon	END_OF_HELP
199a98f50eSThomas Monjalon}
209a98f50eSThomas Monjalon
219a98f50eSThomas Monjalonusage_error () # <message>
229a98f50eSThomas Monjalon{
239a98f50eSThomas Monjalon	echo "$*" >&2
249a98f50eSThomas Monjalon	print_usage >&2
259a98f50eSThomas Monjalon	exit 1
269a98f50eSThomas Monjalon}
279a98f50eSThomas Monjalon
289a98f50eSThomas Monjalonwhile getopts h ARG ; do
299a98f50eSThomas Monjalon	case $ARG in
309a98f50eSThomas Monjalon		h ) print_help ; exit 0 ;;
319a98f50eSThomas Monjalon		? ) print_usage >&2 ; exit 1 ;;
329a98f50eSThomas Monjalon	esac
339a98f50eSThomas Monjalondone
349a98f50eSThomas Monjalonshift $(($OPTIND - 1))
359a98f50eSThomas Monjalon[ $# -ge 1 ] || usage_error 'range argument required'
369a98f50eSThomas Monjalonrange="$*"
379a98f50eSThomas Monjalon
389a98f50eSThomas Monjalon# get major release version of a commit
399a98f50eSThomas Monjaloncommit_version () # <hash>
409a98f50eSThomas Monjalon{
415d65895dSThomas Monjalon	# use current branch as history reference
425d65895dSThomas Monjalon	local refbranch=$(git rev-parse --abbrev-ref HEAD)
435d65895dSThomas Monjalon	local tag=$( (git tag -l --contains $1 --merged $refbranch 2>&- ||
445d65895dSThomas Monjalon		# tag --merged option has been introduced in git 2.7.0
455d65895dSThomas Monjalon		# below is a fallback in case of old git version
465d65895dSThomas Monjalon		for t in $(git tag -l --contains $1) ; do
475d65895dSThomas Monjalon			git branch $refbranch --contains $t |
485d65895dSThomas Monjalon			sed "s,.\+,$t,"
495d65895dSThomas Monjalon		done) |
505d65895dSThomas Monjalon		head -n1)
519a98f50eSThomas Monjalon	if [ -z "$tag" ] ; then
529a98f50eSThomas Monjalon		# before -rc1 tag of release in progress
533cc6ecfdSCiara Power		cat VERSION | cut -d'.' -f-2
549a98f50eSThomas Monjalon	else
559a98f50eSThomas Monjalon		echo $tag | sed 's,^v,,' | sed 's,-rc.*,,'
569a98f50eSThomas Monjalon	fi
579a98f50eSThomas Monjalon}
589a98f50eSThomas Monjalon
599a98f50eSThomas Monjalon# get bug origin hashes of a fix
609a98f50eSThomas Monjalonorigin_filter () # <hash>
619a98f50eSThomas Monjalon{
629a98f50eSThomas Monjalon	git log --format='%b' -1 $1 |
639a98f50eSThomas Monjalon	sed -n 's,^ *\([Ff]ixes\|[Rr]everts\): *\([0-9a-f]*\).*,\2,p'
649a98f50eSThomas Monjalon}
659a98f50eSThomas Monjalon
669a98f50eSThomas Monjalon# get oldest major release version of bug origins
679a98f50eSThomas Monjalonorigin_version () # <origin_hash> ...
689a98f50eSThomas Monjalon{
699a98f50eSThomas Monjalon	for origin in $* ; do
709a98f50eSThomas Monjalon		# check hash is valid
71dbee6968SThomas Monjalon		git rev-parse -q --verify $origin >&- || continue
729a98f50eSThomas Monjalon		# get version of this bug origin
739a98f50eSThomas Monjalon		local origver=$(commit_version $origin)
74df2b82caSThomas Monjalon		local roothashes="$(origin_filter $origin)"
759a98f50eSThomas Monjalon		if [ -n "$roothashes" ] ; then
769a98f50eSThomas Monjalon			# look chained fix of fix recursively
779a98f50eSThomas Monjalon			local rootver="$(origin_version $roothashes)"
789a98f50eSThomas Monjalon			[ -n "$rootver" ] || continue
79cee226c9SChristian Ehrhardt			echo "$rootver (partially fixed in $origin @ $origver)"
809a98f50eSThomas Monjalon		else
819a98f50eSThomas Monjalon			echo "$origver"
829a98f50eSThomas Monjalon		fi
839a98f50eSThomas Monjalon	# filter the oldest origin
849a98f50eSThomas Monjalon	done | sort -uV | head -n1
859a98f50eSThomas Monjalon}
869a98f50eSThomas Monjalon
87*e2e4775cSThomas Monjalon# print a marker for pattern presence in the commit message
88*e2e4775cSThomas Monjalongit_log_mark () # <hash> <pattern> <marker>
8987efbcc7SYuanhan Liu{
90*e2e4775cSThomas Monjalon	if git log --format='%b' -1 $1 | grep -qi "$2" ; then
91*e2e4775cSThomas Monjalon		echo "$3"
928070d8feSKevin Traynor	else
938070d8feSKevin Traynor		echo '-'
948070d8feSKevin Traynor	fi
958070d8feSKevin Traynor}
968070d8feSKevin Traynor
979a98f50eSThomas Monjalongit log --oneline --reverse $range |
989a98f50eSThomas Monjalonwhile read id headline ; do
999a98f50eSThomas Monjalon	origins=$(origin_filter $id)
100*e2e4775cSThomas Monjalon	stable=$(git_log_mark $id '^Cc: *stable@dpdk.org' 'S')
101*e2e4775cSThomas Monjalon	fixes=$(git_log_mark $id '^Fixes:' 'F')
10278bdab09SChristian Ehrhardt	[ "$stable" = "S" ] || [ "$fixes" = "F" ] || [ -n "$origins" ] || continue
1039a98f50eSThomas Monjalon	version=$(commit_version $id)
1049a98f50eSThomas Monjalon	if [ -n "$origins" ] ; then
1059a98f50eSThomas Monjalon		origver="$(origin_version $origins)"
1069a98f50eSThomas Monjalon		[ -n "$origver" ] || continue
1079a98f50eSThomas Monjalon		# ignore fix of bug introduced in the same release
1089a98f50eSThomas Monjalon		! echo "$origver" | grep -q "^$version" || continue
1099a98f50eSThomas Monjalon	else
1109a98f50eSThomas Monjalon		origver='N/A'
1119a98f50eSThomas Monjalon	fi
1128070d8feSKevin Traynor	printf '%s %7s %s %s %s (%s)\n' $version $id $stable $fixes "$headline" "$origver"
1139a98f50eSThomas Monjalondone
114