X-Git-Url: http://gitweb.hugovil.com/?a=blobdiff_plain;f=scripts%2Fkernel-send-patches.sh;h=4e7688fb1c49838e948bf4089c895ecaea887197;hb=1fb7f27af45bc56ba87fd9ad73751fcafb332ee3;hp=091dfa822060b8655323876d8cfbe52bc026173d;hpb=1e9871f06a50adb529695ec7c4e3b7311c4c3f53;p=hvutilities.git diff --git a/scripts/kernel-send-patches.sh b/scripts/kernel-send-patches.sh index 091dfa8..4e7688f 100755 --- a/scripts/kernel-send-patches.sh +++ b/scripts/kernel-send-patches.sh @@ -21,14 +21,22 @@ catch() echo "Error $1 occurred" if [ x"${orig_branch}" != x"" ]; then + if git status | grep -q "currently cherry-picking commit"; then + git cherry-pick --abort + fi + + if git status | grep -q "currently editing a commit while rebasing branch"; then + git rebase --abort + fi + git checkout ${orig_branch} - git rebase --abort fi fi # Cleanup for both normal exit and error: rm -f /tmp/all.patch rm -f ${compile_script} + rm -f /tmp/cover-letter.txt } # --non: do not print name for each email address @@ -36,6 +44,7 @@ TO_CMD="`pwd`/scripts/get_maintainer.pl --nogit --nogit-fallback --norolestats - CC_CMD="`pwd`/scripts/get_maintainer.pl --nogit --nogit-fallback --norolestats --non --nom" # Set default values +debug="0" commit_start="" commit_end="" DRY_RUN="--dry-run" @@ -43,23 +52,36 @@ orig_branch="" srcdir="" compile_cmd="make" compile_script=/tmp/kernel-compile-script.sh +cover="no" +series="" +resend="no" +GIT_FORMAT_PATCH_SUBJECT="PATCH" +GIT_FORMAT_PATCH_OPTS="--histogram" +skip_compile=0 +CHECKPATCH_OPS="--strict" print_usage() { echo "${PROG_NAME} -- Envoi de patches linux kernel" - echo "Usage: ${PROG_NAME} [OPTIONS...] COMMIT_START COMMIT_END" + echo "Usage: ${PROG_NAME} [OPTIONS...]" echo echo "Options:" + echo " -d debug mode" echo " -e end commit (string)" echo " -f folder containing patch infos" echo " -h display this help and exit" + echo " -n dot not compile patches" + echo " -p resend patch" echo " -r really send emails (default = dry-run)" echo " -s start commit (string)" echo } -while getopts "e:f:hrs:" flag ;do +while getopts "de:f:hnprs:" flag ;do case ${flag} in + d) + debug="1" + ;; e) commit_end="${OPTARG}" ;; @@ -70,6 +92,12 @@ while getopts "e:f:hrs:" flag ;do print_usage exit 0 ;; + n) + skip_compile=1 + ;; + p) + resend="yes" + ;; r) DRY_RUN="" ;; @@ -103,9 +131,8 @@ if [ ! -d ${srcdir} ]; then exit 1 fi -if [ ! -f ${srcdir}/cover-letter.txt ]; then - echo "Missing cover letter template" - exit 1 +if [ -f ${srcdir}/cover-letter.txt ]; then + cover="yes" fi if [ ! -f ${srcdir}/infos.sh ]; then @@ -125,23 +152,38 @@ if [ x"${commit_end}" = x"" ]; then exit 1 fi +if [ x"${cover}" = x"yes" ]; then + if [ x"${series}" = x"" ]; then + echo "Missing series shell variable" + exit 1 + fi -if [ x"${series}" = x"" ]; then - echo "Missing series shell variable" - exit 1 + if [ x"${subject}" = x"" ]; then + echo "Missing subject shell variable" + exit 1 + fi fi -if [ x"${subject}" = x"" ]; then - echo "Missing subject shell variable" +if [ x"${cc_list}" = x"" ]; then + echo "Missing cc_list shell variable" exit 1 fi -if [ x"${cc_list}" = x"" ]; then - echo "Missing cc_list shell variable" +if [ x"${base_branch}" = x"" ]; then + echo "Missing base_branch shell variable" exit 1 fi -patches_branch="kernel_send_patches_v${series}_$(basename ${srcdir})" +if [ ${skip_compile} -eq 0 ]; then + if [ x"${compile_branch}" = x"" ]; then + echo "Missing compile_branch shell variable" + exit 1 + fi +fi + +if [ x"${base_commit}" = x"" ]; then + base_commit="auto" +fi # First arg: commit message find_commit_by_log() @@ -149,6 +191,32 @@ find_commit_by_log() echo $(git log --oneline HEAD~100..HEAD | grep "${1}" | awk {'print $1'}) } +# Find SHA1 of preceding commit: +# First arg: commit message +find_preceding_commit_by_log() +{ + local sha1_end + + sha1_end="$(find_commit_by_log "${1}")" + echo $(git log --oneline ${sha1_end}~2..${sha1_end}~1 | awk {'print $1'}) +} + +# Remove "Name" if present in email address. Needed because of a bug in +# get_maintainer.pl even if we specify the "--non" option. +# Arg #1: "Name " or "email" +format_email() +{ + local mail="${1}" + + if echo "${mail}" | grep -q '<'; then + mail=$(echo ${mail} | sed "s@.*<\(.*\)>@\1@") + else + mail="${mail}" + fi + + echo "${mail}" +} + # Because the cover letter is a special case and not a real patch, running # get_maintainer.pl on it would not return any TO or CC addresses. # Therefore, manually run get_maintainer.pl on the concatenation of all the @@ -156,20 +224,25 @@ find_commit_by_log() # all emails, including cover letter and actual patches. collect_email_addresses() { - cat ${srcdir}/v${series}-*.patch > /tmp/all.patch + cat ${srcdir}/*.patch > /tmp/all.patch # These variables will have one email address per line" TO_MAIL="$(${TO_CMD} /tmp/all.patch)" CC_MAIL="$(${CC_CMD} /tmp/all.patch)" while IFS= read -r line; do + line=$(format_email "${line}") TO_OPTS="${TO_OPTS} --to ${line}" done <<< "${TO_MAIL}" while IFS= read -r line; do + line=$(format_email "${line}") CC_OPTS="${CC_OPTS} --cc ${line}" done <<< "${CC_MAIL}" +} +add_cc_list_addresses() +{ for address in ${cc_list}; do CC_OPTS="${CC_OPTS} --cc ${address}" done @@ -189,21 +262,77 @@ if [ x"${COMMIT_END_SHA1}" = x"" ]; then exit 1 fi +if echo "${commit_end}" | grep -q "^end"; then + # Take commit just before end commit: + COMMIT_END_SHA1=$(find_preceding_commit_by_log "${commit_end}") +fi + rm -rf ${srcdir}/*.patch -git format-patch -v ${series} --output-directory=${srcdir} --cover-letter ${COMMIT_START_SHA1}..${COMMIT_END_SHA1} +# If the cover letter is not between start and end commits, save a copy: +cp ${srcdir}/cover-letter.txt /tmp -# Replace subject line in cover letter: -sed -i -e "s/\*\*\* SUB.*/${subject}/" ${srcdir}/v${series}-0000-cover-letter.patch +patches_branch="hv_send_patches_$(basename ${srcdir})" -# Replace blurb line in cover letter: -sed -i -e "/.*BLURB.*/{r ${srcdir}/cover-letter.txt" -e 'd}' ${srcdir}/v${series}-0000-cover-letter.patch +if [ x"${series}" != x"" ]; then + patches_branch="${patches_branch}_v${series}" +fi -collect_email_addresses +orig_branch=$(git branch --show-current) + +if [ x"${orig_branch}" = x"" ]; then + echo "Error: unable to determine current branch" + exit 1 +fi + +if git branch | grep -q ${patches_branch}; then + git branch -D ${patches_branch} 1>/dev/null +fi + +if [ "${debug}" = "1" ]; then + echo "start commit: ${COMMIT_START_SHA1}" + echo "end commit: ${COMMIT_END_SHA1}" +fi + +# Create new branch from base_branch, and apply all our patches onto it: +git checkout -b ${patches_branch} ${base_branch} +git branch --set-upstream-to ${base_branch} +git cherry-pick ${COMMIT_START_SHA1}..${COMMIT_END_SHA1} + +GIT_FORMAT_PATCH_OPTS="${GIT_FORMAT_PATCH_OPTS} --base=${base_commit}" + +if [ x"${cover}" = x"yes" ]; then + GIT_FORMAT_PATCH_OPTS="${GIT_FORMAT_PATCH_OPTS} --cover-letter" +fi + +series_prefix="" +if [ x"${series}" != x"" -a x"${series}" != x"1" ]; then + series_prefix="v${series}-" + GIT_FORMAT_PATCH_OPTS="${GIT_FORMAT_PATCH_OPTS} -v ${series}" +fi + +if [ x"${resend}" = x"yes" ]; then + GIT_FORMAT_PATCH_SUBJECT="RESEND ${GIT_FORMAT_PATCH_SUBJECT}" +fi + +git format-patch --subject-prefix="${GIT_FORMAT_PATCH_SUBJECT}" \ + ${GIT_FORMAT_PATCH_OPTS} --output-directory=${srcdir} ${base_branch} + +if [ x"${cover}" = x"yes" ]; then + # Replace subject line in cover letter: + sed -i -e "s@\*\*\* SUB.*@${subject}@" ${srcdir}/${series_prefix}0000-cover-letter.patch + + # Replace blurb line in cover letter: + sed -i -e "/.*BLURB.*/{r /tmp/cover-letter.txt" -e 'd}' ${srcdir}/${series_prefix}0000-cover-letter.patch + + collect_email_addresses +fi + +add_cc_list_addresses # Check patches (except special case of cover letter patch): for p in ${srcdir}/*.patch; do - if [ x"$(basename ${p})" != x"v${series}-0000-cover-letter.patch" ]; then + if [ x"$(basename ${p})" != x"${series_prefix}0000-cover-letter.patch" ]; then if [ x"${ignore_checkpatch_errors}" != x"" ]; then set +e CHECKPATCH_OPS="--ignore ${ignore_checkpatch_errors}" @@ -217,33 +346,45 @@ for p in ${srcdir}/*.patch; do fi done -orig_branch=$(git branch --show-current) - -if [ x"${orig_branch}" = x"" ]; then - echo "Error: unable to determine current branch" - exit 1 -fi - -cat > ${compile_script} << "EOF" +if [ ${skip_compile} -eq 0 ]; then + cat > ${compile_script} << "EOF" #!/bin/bash # Do not edit, auto-generated script echo echo "Testing commit: $(git log --oneline | head -n 1)" +#INIT_CMD COMPILE_CMD EOF -sed -i -e "s@COMPILE_CMD@${compile_cmd}@" ${compile_script} -chmod u+x ${compile_script} + if [ x"${init_cmd}" != x"" ]; then + sed -i -e "s@.*INIT_CMD@${init_cmd}@" ${compile_script} + fi + sed -i -e "s@COMPILE_CMD@${compile_cmd}@" ${compile_script} + chmod u+x ${compile_script} + + # Create temporary branch for compilation, based on compile_branch: + temp_compile_branch="${patches_branch}_compile" -# Compile each commit. Create branch to avoid "detached HEAD" state, and also to -# keep a record of what was sent: -if git branch | grep -q ${patches_branch}; then - git branch -D ${patches_branch} + if git branch | grep -q ${temp_compile_branch}; then + git branch -D ${temp_compile_branch} + fi + + git checkout -b ${temp_compile_branch} ${compile_branch} + + # Apply all of our commits to temp_compile_branch: + git cherry-pick ${COMMIT_START_SHA1}..${COMMIT_END_SHA1} + + # Compile and test each commit: + git rebase --exec=${compile_script} ${compile_branch} fi -git checkout -b ${patches_branch} ${COMMIT_END_SHA1} -git rebase --exec=${compile_script} ${COMMIT_START_SHA1} + git checkout ${orig_branch} +if [ ${skip_compile} -eq 0 ]; then + # Remove temporary branch: + git branch -D ${temp_compile_branch} +fi + # Send email(s) git send-email ${DRY_RUN} --annotate --thread --no-chain-reply-to \ ${TO_OPTS} ${CC_OPTS} \