1#!/bin/sh 2# 3# Copyright (c) 2010-2013, Intel Corporation. 4# 5# SPDX-License-Identifier: GPL-2.0-or-later 6# 7 8# 9# This script is intended to be used to prepare a series of patches 10# and a cover letter in an appropriate and consistent format for 11# submission to Open Embedded and The Yocto Project, as well as to 12# related projects and layers. 13# 14 15ODIR=pull-$$ 16RELATIVE_TO="master" 17COMMIT_ID="HEAD" 18PREFIX="PATCH" 19RFC=0 20 21usage() { 22CMD=$(basename $0) 23cat <<EOM 24Usage: $CMD [-h] [-o output_dir] [-m msg_body_file] [-s subject] [-r relative_to] [-i commit_id] [-d relative_dir] -u remote [-b branch] [-- <format-patch options>] 25 -b branch Branch name in the specified remote (default: current branch) 26 -l local branch Local branch name (default: HEAD) 27 -c Create an RFC (Request for Comment) patch series 28 -h Display this help message 29 -a Automatically push local branch (-l) to remote branch (-b), 30 or set CPR_CONTRIB_AUTO_PUSH in env 31 -i commit_id Ending commit (default: HEAD) 32 -m msg_body_file The file containing a blurb to be inserted into the summary email 33 -o output_dir Specify the output directory for the messages (default: pull-PID) 34 -p prefix Use [prefix N/M] instead of [PATCH N/M] as the subject prefix 35 -r relative_to Starting commit (default: master) 36 -s subject The subject to be inserted into the summary email 37 -u remote The git remote where the branch is located, or set CPR_CONTRIB_REMOTE in env 38 -d relative_dir Generate patches relative to directory 39 40 Examples: 41 $CMD -u contrib -b nitin/basic 42 $CMD -u contrib -r distro/master -i nitin/distro -b nitin/distro 43 $CMD -u contrib -r distro/master -i nitin/distro -b nitin/distro -l distro 44 $CMD -u contrib -r master -i misc -b nitin/misc -o pull-misc 45 $CMD -u contrib -p "RFC PATCH" -b nitin/experimental 46 $CMD -u contrib -i misc -b nitin/misc -d ./bitbake 47 $CMD -u contrib -r origin/master -o /tmp/out.v3 -- -v3 --in-reply-to=20170511120134.XX7799@site.com 48EOM 49} 50 51REMOTE="$CPR_CONTRIB_REMOTE" 52# Parse and validate arguments 53while getopts "b:acd:hi:m:o:p:r:s:u:l:" OPT; do 54 case $OPT in 55 b) 56 BRANCH="$OPTARG" 57 ;; 58 l) 59 L_BRANCH="$OPTARG" 60 ;; 61 c) 62 RFC=1 63 ;; 64 d) 65 RELDIR="$OPTARG" 66 ;; 67 h) 68 usage 69 exit 0 70 ;; 71 i) 72 COMMIT_ID="$OPTARG" 73 ;; 74 m) 75 BODY="$OPTARG" 76 if [ ! -e "$BODY" ]; then 77 echo "ERROR: Body file does not exist" 78 exit 1 79 fi 80 ;; 81 o) 82 ODIR="$OPTARG" 83 ;; 84 p) 85 PREFIX="$OPTARG" 86 ;; 87 r) 88 RELATIVE_TO="$OPTARG" 89 ;; 90 s) 91 SUBJECT="$OPTARG" 92 ;; 93 u) 94 REMOTE="$OPTARG" 95 ;; 96 a) 97 CPR_CONTRIB_AUTO_PUSH="1" 98 ;; 99 --) 100 shift 101 break 102 ;; 103 esac 104done 105 106shift "$((OPTIND - 1))" 107extraopts="$@" 108 109if [ -z "$REMOTE" ]; then 110 echo "ERROR: Missing parameter -u or CPR_CONTRIB_REMOTE in env, no git remote!" 111 usage 112 exit 1 113fi 114 115REMOTE_URL=$(git config remote.$REMOTE.url) 116if [ $? -ne 0 ]; then 117 echo "ERROR: git config failed to find a url for '$REMOTE'" 118 echo 119 echo "To add a remote url for $REMOTE, use:" 120 echo " git config remote.$REMOTE.url <url>" 121 exit 1 122fi 123 124# Rewrite private URLs to public URLs 125# Determine the repository name for use in the WEB_URL later 126USER_RE="[A-Za-z0-9_.@][A-Za-z0-9_.@-]*\$\?" 127PROTO_RE="[a-z][a-z+]*://" 128GIT_RE="\(^\($PROTO_RE\)\?\)\($USER_RE@\)\?\([^:/]*\)[:/]\(.*\)" 129REMOTE_URL=${REMOTE_URL%.git} 130REMOTE_REPO=$(echo $REMOTE_URL | sed "s#$GIT_RE#\5#") 131REMOTE_URL=$(echo $REMOTE_URL | sed "s#$GIT_RE#https://\4/\5#") 132 133if [ -z "$BRANCH" ]; then 134 BRANCH=$(git branch | grep -e "^\* " | cut -d' ' -f2) 135 echo "NOTE: Assuming remote branch '$BRANCH', use -b to override." 136fi 137 138if [ -z "$L_BRANCH" ]; then 139 L_BRANCH=HEAD 140 echo "NOTE: Assuming local branch HEAD, use -l to override." 141fi 142 143if [ $RFC -eq 1 ]; then 144 PREFIX="RFC $PREFIX" 145fi 146 147 148# Set WEB_URL from known remotes 149WEB_URL="" 150case "$REMOTE_URL" in 151 *git.yoctoproject.org*) 152 WEB_URL="https://git.yoctoproject.org/$REMOTE_REPO/log/?h=$BRANCH" 153 ;; 154 *git.openembedded.org*) 155 WEB_URL="https://git.openembedded.org/$REMOTE_REPO/log/?h=$BRANCH" 156 ;; 157 *github.com*) 158 WEB_URL="https://github.com/$REMOTE_REPO/tree/$BRANCH" 159 ;; 160esac 161 162# Perform a sanity test on the web URL. Issue a warning if it is not 163# accessible, but do not abort as users may want to run offline. 164if [ -n "$WEB_URL" ]; then 165 if [ "$CPR_CONTRIB_AUTO_PUSH" = "1" ]; then 166 echo "Pushing '$BRANCH' on '$REMOTE' as requested..." 167 git push $REMOTE $L_BRANCH:$BRANCH 168 echo "" 169 fi 170 wget --no-check-certificate -q $WEB_URL -O /dev/null 171 if [ $? -ne 0 ]; then 172 echo "WARNING: Branch '$BRANCH' was not found on the contrib git tree." 173 echo " Please check your remote and branch parameter before sending." 174 echo "" 175 fi 176fi 177 178if [ -e $ODIR ]; then 179 echo "ERROR: output directory $ODIR exists." 180 exit 1 181fi 182mkdir $ODIR 183 184if [ -n "$RELDIR" ]; then 185 ODIR=$(realpath $ODIR) 186 pdir=$(pwd) 187 cd $RELDIR 188 extraopts="$extraopts --relative" 189fi 190 191# Generate the patches and cover letter 192git format-patch $extraopts -M40 --subject-prefix="$PREFIX" -n -o $ODIR --thread=shallow --cover-letter $RELATIVE_TO..$COMMIT_ID > /dev/null 193 194if [ -z "$(ls -A $ODIR 2> /dev/null)" ]; then 195 echo "ERROR: $ODIR is empty, no cover letter and patches was generated!" 196 echo " This is most likely due to that \$RRELATIVE_TO..\$COMMIT_ID" 197 echo " ($RELATIVE_TO..$COMMIT_ID) don't contain any differences." 198 rmdir $ODIR 199 exit 1 200fi 201 202[ -n "$RELDIR" ] && cd $pdir 203 204# Customize the cover letter 205CL="$(echo $ODIR/*0000-cover-letter.patch)" 206PM="$ODIR/pull-msg" 207GIT_VERSION=$(`git --version` | tr -d '[:alpha:][:space:].' | sed 's/\(...\).*/\1/') 208NEWER_GIT_VERSION=210 209if [ $GIT_VERSION -lt $NEWER_GIT_VERSION ]; then 210 git request-pull $RELATIVE_TO $REMOTE_URL $COMMIT_ID >> "$PM" 211else 212 git request-pull $RELATIVE_TO $REMOTE_URL $L_BRANCH:$BRANCH >> "$PM" 213fi 214if [ $? -ne 0 ]; then 215 echo "ERROR: git request-pull reported an error" 216 rm -rf $ODIR 217 exit 1 218fi 219 220# The cover letter already has a diffstat, remove it from the pull-msg 221# before inserting it. 222sed -n "0,\#$REMOTE_URL# p" "$PM" | sed -i "/BLURB HERE/ r /dev/stdin" "$CL" 223rm "$PM" 224 225# If this is an RFC, make that clear in the cover letter 226if [ $RFC -eq 1 ]; then 227(cat <<EOM 228Please review the following changes for suitability for inclusion. If you have 229any objections or suggestions for improvement, please respond to the patches. If 230you agree with the changes, please provide your Acked-by. 231 232EOM 233) | sed -i "/BLURB HERE/ r /dev/stdin" "$CL" 234fi 235 236# Insert the WEB_URL if there is one 237if [ -n "$WEB_URL" ]; then 238 echo " $WEB_URL" | sed -i "\#$REMOTE_URL# r /dev/stdin" "$CL" 239fi 240 241 242# If the user specified a message body, insert it into the cover letter and 243# remove the BLURB token. 244if [ -n "$BODY" ]; then 245 sed -i "/BLURB HERE/ r $BODY" "$CL" 246 sed -i "/BLURB HERE/ d" "$CL" 247fi 248 249# Set subject automatically if there is only one patch 250patch_cnt=`git log --pretty=oneline ${RELATIVE_TO}..${L_BRANCH} | wc -l` 251if [ -z "$SUBJECT" -a $patch_cnt -eq 1 ]; then 252 SUBJECT="`git log --format=%s ${RELATIVE_TO}..${L_BRANCH}`" 253fi 254 255# Replace the SUBJECT token with it. 256if [ -n "$SUBJECT" ]; then 257 sed -i -e "s\`\*\*\* SUBJECT HERE \*\*\*\`$SUBJECT\`" "$CL" 258fi 259 260 261# Generate report for user 262cat <<EOM 263The following patches have been prepared: 264$(for PATCH in $(ls $ODIR/*); do echo " $PATCH"; done) 265 266Review their content, especially the summary mail: 267 $CL 268 269When you are satisfied, you can send them with: 270 send-pull-request -a -p $ODIR 271EOM 272 273# Check the patches for trailing white space 274egrep -q -e "^\+.*\s+$" $ODIR/* 275if [ $? -ne 1 ]; then 276 echo 277 echo "WARNING: Trailing white space detected at these locations" 278 egrep -nH --color -e "^\+.*\s+$" $ODIR/* 279fi 280