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
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"
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}"
;;
print_usage
exit 0
;;
+ n)
+ skip_compile=1
+ ;;
+ p)
+ resend="yes"
+ ;;
r)
DRY_RUN=""
;;
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
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()
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 <email>" 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
# 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
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}"
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} \