blob: 583e9ac9988c2d1c49c8ebdb515162f30740715c [file] [log] [blame]
#!/bin/bash
#
# Try to grab commits from one stable tree into another, stopping to fix
# backports if required.
#
function pick_one {
# Let's try cherry-picking the given commit first.
git cherry-pick --strategy=recursive -Xpatience -x $1 &> /dev/null
if [ $? -gt "0" ]; then
git reset --hard
# That didn't work? Let's try that with every variation of the commit
# in other stable trees.
for i in $(stable-find-alts $1); do
git cherry-pick --strategy=recursive -Xpatience -x $i &> /dev/null
if [ $? = "0" ]; then
return 0
fi
git reset --hard
done
# Still no? Let's go back to the original commit and hand it off to
# the user.
git cherry-pick --strategy=recursive -Xpatience -x $1 &> /dev/null
fi
return $?
}
function check_relevant {
cmt=$1
maj=0
min=0
# Let's grab the commit that this commit fixes (if exists (based on the "Fixes:" tag)).
fixescmt=`git show $cmt | grep -i "fixes:" | head -n 1 | sed -e 's/^[ \t]*//' | cut -f 2 -d ':' | sed -e 's/^[ \t]*//' | cut -f 1 -d ' '`
# If this commit fixes anything, but the broken commit isn't in our branch we don't
# need this commit either.
if [ "$fixescmt" != "" ] && [ "$(stable-commit-in-tree $fixescmt)" = "1" ]; then
return 0
fi
# Let's see if there's a version tag in this commit
full=$(git show $cmt | grep -i 'stable@vger')
full=$(echo ${full##* } | tr -cd '[[:digit:]]._-' | sed 's/]//g' | sed 's/\[//g' | sed 's/\./ /g')
maj=$(echo $full | awk {"print \$1"})
min=$(echo $full | awk {"print \$2"})
# Sanity check our extraction
if [ "$(echo ${full##* } | grep 'stable' | wc -l)" -gt "0" ]; then
return 1
fi
# Sanity check major version
if [ "$maj" != "2" ] && [ "$maj" != "3" ] && [ "$maj" != "4" ]; then
return 1
fi
# If the version tag is for a major version newer than ours
if [ "STABLE_MAJ_VER" -gt "$maj" ]; then
return 1
fi
# Or if the overall version is newer than ours
if [ "STABLE_MAJ_VER" -eq "$maj" ] && [ "STABLE_MIN_VER" -ge "$min" ]; then
return 1
fi
# No version tag, unsure, or version tag is older than ours
return 0
}
function do_one {
for i in $(git log --no-merges --format="%H" $1 $2 | tac); do
subj=$(git log -1 --format="%s" $i)
# Let's grab the mainline commit id, this is useful if the version tag
# doesn't exist in the commit we're looking at but exists upstream.
orig_cmt=$(git log --no-merges --format="%H" -F --grep "$subj" origin/master | tail -n1)
# If the commit doesn't apply for us, skip it
check_relevant $orig_cmt
if [ $? -eq "0" ]; then
continue
fi
pick_one $i
if [ $? -gt 0 ] ; then
echo "Cherry pick failed. Fix, commit (or reset) and exit."
/bin/sh
continue
fi
# If we didn't find the commit upstream then this must be a custom commit
# in the given tree - make sure the user checks this commit.
if [ "$orig_cmt" = "" ] ; then
msg="Custom"
orig_cmt=$(git rev-parse HEAD)
echo "Custom commit, please double-check!"
/bin/sh
fi
stable-make-pretty $orig_cmt $msg
done
}
if [ "$#" -ne 1 ] && [ "$#" -ne 2 ]; then
echo "Usage: stable steal-commits <commit range> [branch]"
exit 1
fi
do_one $1 $2