rh-utils: add script find-backports.sh

When backporting commits, we should do `git cherry-pick -x`,
so that the commit message contains:
    (cherry picked from commit $SHA)

Similarly, when fixing an actual bug of a previous commit, we
mark the faulty commit with:
    Fixes: $SHA

This script walks through a commit range of a stable branch,
and finds all $BACKPORTED_COMMITS (the sources from where we
cherry-picked).
Then it walks through a commit range of upstream/unstable branch,
and searches for $FIXES of the $BACKPORTED_COMMITS.

Then it prints all $FIXES, that are not yet backported. You probably
should backport those commits as well.
This commit is contained in:
Thomas Haller 2015-08-07 12:57:11 +02:00 committed by Lubomir Rintel
parent 0752bd18bd
commit 0987f7f61e

View file

@ -0,0 +1,87 @@
#!/bin/bash
die() {
echo "$@" >&2
exit 1
}
print_usage() {
echo "$0 [REF_BASE REF_STABLE REF_UPSTREAM]"
echo " for example $0 1.1.0-dev~ nm-1-0 master"
}
ref_exists() {
git rev-parse --verify "$1" &> /dev/null
}
get_cherry_picked_from() {
local H="$1"
local B
for B in $(git log -n1 "$H" 2>&1 | sed -n -e 's/.*cherry.picked.*\<\([0-9a-f]\{6,40\}\)\>.*/\1/p'); do
if ref_exists "$B"; then
echo $B
# if the original patch was cherry-picked too, continue
# recursively.
get_cherry_picked_from "$B"
fi
done
}
get_backported_all() {
local RANGE="$1"
local H
for H in $(git log --pretty="%H" "$RANGE"); do
get_cherry_picked_from "$H"
done |
sort | uniq
}
get_fixes() {
local RANGE="$1"
local BACKPORTED="$2"
local H B
for H in $BACKPORTED; do
for B in $(git log --format="%H" --no-walk --grep '[Ff]ixes: *'"${H:0:7}" "$RANGE"); do
echo "$B"
# if commit $B fixes $H, and commit $B was itself backported (cherry-picked),
# then also all original versions of $B fix $H.
get_cherry_picked_from "$B"
done
done |
sort | uniq
}
if [[ "$#" != 3 && "$#" != 0 ]]; then
print_usage
die "Wrong arguments"
fi
if [[ "$#" == 3 ]]; then
REF_BASE="$1"
REF_STABLE="$2"
REF_UPSTREAM="$3"
else
REF_BASE=1.1.0-dev~
REF_STABLE=nm-1-0
REF_UPSTREAM=master
fi
ref_exists "$REF_BASE" || die "Invalid REF_BASE=\"$REF_BASE\""
ref_exists "$REF_UPSTREAM" || die "Invalid REF_UPSTREAM=\"$REF_UPSTREAM\""
ref_exists "$REF_STABLE" || die "Invalid REF_STABLE=\"$REF_STABLE\""
BACKPORTED="$(get_backported_all "$REF_BASE..$REF_STABLE")"
FIXES="$(get_fixes "$REF_BASE..$REF_UPSTREAM" "$BACKPORTED")"
MISSING_BACKPORTS="$(printf '%s' "$FIXES" | grep $(printf '%s' "$BACKPORTED" | sed 's/^/-e /') - -v)"
if [ -n "$MISSING_BACKPORTS" ]; then
git log -p --no-walk $(echo "$MISSING_BACKPORTS")
printf "%s\n" "$MISSING_BACKPORTS"
fi