blob: 4a2564b4c6c507c66f814cdcd2502538ffac73ea [file] [log] [blame]
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2019 Daniel Borkmann <daniel@iogearbox.net>
# Copyright (C) 2020 Jakub Kicinski <kuba@kernel.org>
# Pull from a pull request in patchwork, add a commit message
# based on the contents of the tag or the email if tag was empty.
# Optionally, compare if the patches on the branch are identical
# to what's posted on the mailing list.
source $(dirname $0)/lib.sh
usage()
{
cat <<-EOF
usage: pw-pull [-p PULL] [-s SERIES] [-c] [-P PULL_URL] [-h]
EOF
exit
}
pull=""
pull_url=""
cover=""
series=""
series_branch="tmp"
head_old=$(git rev-parse --verify HEAD)
while true; do
case "$1" in
-p | --pull ) pull="$2"; shift 2 ;;
-s | --series ) series="$2"; shift 2 ;;
-c | --pull-from-cover ) cover="y"; shift ;;
-P | --pull-url ) pull_url="$2"; shift 2 ;;
-h | --help ) usage; break ;;
-- ) shift; break ;;
* ) break ;;
esac
done
[ -z "$pull" ] && [ -z "$cover" ] && [ -z "$pull_url" ] && usage
[ ! -z "$pull" ] && [ ! -z "$cover" ] && usage
[ ! -z "$pull" ] && [ ! -z "$pull_url" ] && usage
srv=$(git config --get pw.server)
srv=${srv%/} # strip trailing slash
if [ ! -z "$pull" ]; then
pull_json=$(curl -s $srv/patches/$pull/)
pull_url=$(echo "$pull_json" | jq -r '.pull_url')
pull_author=$(echo "$pull_json" | jq -r '.submitter.name')
pull_subject=$(echo "$pull_json" |
jq -r '.name' |
sed -e 's/\[.*\] *//')
pull_msgid=$(echo "$pull_json" | jq -r '.msgid' | tr -d '<>')
json=$pull_json
elif [ ! -z "$cover" ]; then
series_json=$(curl -s $srv/series/$series/)
pull_author=$(echo "$series_json" | jq -r '.submitter.name')
pull_subject=$(echo "$series_json" |
jq -r '.name' |
sed -e 's/\[.*\] *//')
pull_msgid=$(echo "$series_json" | jq -r '.cover_letter.msgid' | tr -d '<>')
cover_id=$(echo "$series_json" | jq -r '.cover_letter.id')
cover_json=$(curl -s $srv/covers/$cover_id/)
pull_msg=$(echo "$pull" |
jq -r '.content' |
awk 'BEGIN {e=0}
/^---/ {e=1}
/^Please consider/ {e=1}
{if(!e) print}')
if [ -z "$pull_url" ]; then
pull_url=$(echo "$cover_json" |
jq -r '.content' |
awk '/^.+$/ { if (n) {n=0; print} }
/and are available in the git repository at:/ {n=1}')
pull_url=$(echo $pull_url)
fi
if [ -z "$pull_url" ]; then
echo "Unable to parse out pull URL"
exit 1
fi
json=$cover_json
fi
# Download the series from ML and make a local branch
if [ ! -z "$series" ]; then
mbox_from_series $series
git checkout -b $series_branch
git am -3 mbox.i
rm -f mbox.i
git checkout master
fi
git pull --stat --log --no-edit --no-ff $pull_url
merge_header=$(git show --format="%s" --no-patch)
merge_body=$(git show --format="%b" --no-patch)
# count lines until "* tag", ignore empty and gpg output
significant_lines=$(echo -e "$merge_body" |
awk 'BEGIN {c=0; e=0}
/^\* (tag|git|https|'"'"')/ {e=1}
/^[^#]/ { if(!e) c++}
END {print c}')
if [ "$significant_lines" -le 1 ]; then
# Construct the message from email body if tag is empty
pull_msg=$(echo "$json" |
jq -r '.content' |
awk 'BEGIN {e=0}
/^---/ {e=1}
/^The following changes since commit/ {e=1}
/^The following are changes since commit/ {e=1}
/^Please consider/ {e=1}
/^Please, pull these changes/ {e=1}
{if(!e) print}')
git commit --amend --signoff -F- <<EOF
$merge_header
$pull_author says:
====================
$pull_subject
$pull_msg
$merge_body
====================
Link: https://lore.kernel.org/r/$pull_msgid
EOF
else
# Tag has info in it, just use that
git commit --amend --signoff -F- <<EOF
$merge_header
$pull_author says:
====================
$merge_body
====================
Link: https://lore.kernel.org/r/$pull_msgid
EOF
fi
if [ ! -z "$series" ]; then
if git diff master..$series_branch --exit-code; then
echo -e '\e[0;32mSeries matches PR\e[0m'
else
echo -e '\n\n\e[1;31mSeries differs!!\e[0m\n'
fi
git branch -D $series_branch
fi
git commit --amend
# Checks
head_new=$(git rev-parse --verify HEAD)
pw-check -s $head_old -e $head_new