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#git://\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="http://git.yoctoproject.org/cgit.cgi/$REMOTE_REPO/log/?h=$BRANCH" 153 ;; 154 *git.pokylinux.org*) 155 WEB_URL="http://git.pokylinux.org/cgit.cgi/$REMOTE_REPO/log/?h=$BRANCH" 156 ;; 157 *git.openembedded.org*) 158 WEB_URL="http://cgit.openembedded.org/$REMOTE_REPO/log/?h=$BRANCH" 159 ;; 160 *github.com*) 161 WEB_URL="https://github.com/$REMOTE_REPO/tree/$BRANCH" 162 ;; 163esac 164 165# Perform a sanity test on the web URL. Issue a warning if it is not 166# accessible, but do not abort as users may want to run offline. 167if [ -n "$WEB_URL" ]; then 168 if [ "$CPR_CONTRIB_AUTO_PUSH" = "1" ]; then 169 echo "Pushing '$BRANCH' on '$REMOTE' as requested..." 170 git push $REMOTE $L_BRANCH:$BRANCH 171 echo "" 172 fi 173 wget --no-check-certificate -q $WEB_URL -O /dev/null 174 if [ $? -ne 0 ]; then 175 echo "WARNING: Branch '$BRANCH' was not found on the contrib git tree." 176 echo " Please check your remote and branch parameter before sending." 177 echo "" 178 fi 179fi 180 181if [ -e $ODIR ]; then 182 echo "ERROR: output directory $ODIR exists." 183 exit 1 184fi 185mkdir $ODIR 186 187if [ -n "$RELDIR" ]; then 188 ODIR=$(realpath $ODIR) 189 pdir=$(pwd) 190 cd $RELDIR 191 extraopts="$extraopts --relative" 192fi 193 194# Generate the patches and cover letter 195git format-patch $extraopts -M40 --subject-prefix="$PREFIX" -n -o $ODIR --thread=shallow --cover-letter $RELATIVE_TO..$COMMIT_ID > /dev/null 196 197if [ -z "$(ls -A $ODIR 2> /dev/null)" ]; then 198 echo "ERROR: $ODIR is empty, no cover letter and patches was generated!" 199 echo " This is most likely due to that \$RRELATIVE_TO..\$COMMIT_ID" 200 echo " ($RELATIVE_TO..$COMMIT_ID) don't contain any differences." 201 rmdir $ODIR 202 exit 1 203fi 204 205[ -n "$RELDIR" ] && cd $pdir 206 207# Customize the cover letter 208CL="$(echo $ODIR/*0000-cover-letter.patch)" 209PM="$ODIR/pull-msg" 210GIT_VERSION=$(`git --version` | tr -d '[:alpha:][:space:].' | sed 's/\(...\).*/\1/') 211NEWER_GIT_VERSION=210 212if [ $GIT_VERSION -lt $NEWER_GIT_VERSION ]; then 213 git request-pull $RELATIVE_TO $REMOTE_URL $COMMIT_ID >> "$PM" 214else 215 git request-pull $RELATIVE_TO $REMOTE_URL $L_BRANCH:$BRANCH >> "$PM" 216fi 217if [ $? -ne 0 ]; then 218 echo "ERROR: git request-pull reported an error" 219 rm -rf $ODIR 220 exit 1 221fi 222 223# The cover letter already has a diffstat, remove it from the pull-msg 224# before inserting it. 225sed -n "0,\#$REMOTE_URL# p" "$PM" | sed -i "/BLURB HERE/ r /dev/stdin" "$CL" 226rm "$PM" 227 228# If this is an RFC, make that clear in the cover letter 229if [ $RFC -eq 1 ]; then 230(cat <<EOM 231Please review the following changes for suitability for inclusion. If you have 232any objections or suggestions for improvement, please respond to the patches. If 233you agree with the changes, please provide your Acked-by. 234 235EOM 236) | sed -i "/BLURB HERE/ r /dev/stdin" "$CL" 237fi 238 239# Insert the WEB_URL if there is one 240if [ -n "$WEB_URL" ]; then 241 echo " $WEB_URL" | sed -i "\#$REMOTE_URL# r /dev/stdin" "$CL" 242fi 243 244 245# If the user specified a message body, insert it into the cover letter and 246# remove the BLURB token. 247if [ -n "$BODY" ]; then 248 sed -i "/BLURB HERE/ r $BODY" "$CL" 249 sed -i "/BLURB HERE/ d" "$CL" 250fi 251 252# Set subject automatically if there is only one patch 253patch_cnt=`git log --pretty=oneline ${RELATIVE_TO}..${L_BRANCH} | wc -l` 254if [ -z "$SUBJECT" -a $patch_cnt -eq 1 ]; then 255 SUBJECT="`git log --format=%s ${RELATIVE_TO}..${L_BRANCH}`" 256fi 257 258# Replace the SUBJECT token with it. 259if [ -n "$SUBJECT" ]; then 260 sed -i -e "s\`\*\*\* SUBJECT HERE \*\*\*\`$SUBJECT\`" "$CL" 261fi 262 263 264# Generate report for user 265cat <<EOM 266The following patches have been prepared: 267$(for PATCH in $(ls $ODIR/*); do echo " $PATCH"; done) 268 269Review their content, especially the summary mail: 270 $CL 271 272When you are satisfied, you can send them with: 273 send-pull-request -a -p $ODIR 274EOM 275 276# Check the patches for trailing white space 277egrep -q -e "^\+.*\s+$" $ODIR/* 278if [ $? -ne 1 ]; then 279 echo 280 echo "WARNING: Trailing white space detected at these locations" 281 egrep -nH --color -e "^\+.*\s+$" $ODIR/* 282fi 283