1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
|
#!/bin/sh
#
# typical usage:
# push-pcp -b main -t pcp -r 6bad98e4b0537c2e99b3906ca7a36f4998ea3419..
#
# cd to the base of the current PCP repo
#
_here=`pwd`
_cwd="$_here"
while true
do
# looks like git repo
#
if [ -d .git ]
then
# now is the origin a clone of the official PCP repo?
#
if git config --get remote.origin.url | grep '/github.com.*/pcp$' >/dev/null
then
break
fi
fi
cd ..
_next_cwd=`pwd`
if [ "$_next_cwd" = "$_cwd" ]
then
# back to / and no luck
echo >&2 "Error: no PCP git repo between cwd and /"
cd "$_here"
exit
fi
_cwd="$_next_cwd"
done
origin_url=`git config --get remote.origin.url`
tmp=/var/tmp/$$
trap "rm -f $tmp.*; exit 0" 0 1 2 3 15
_usage()
{
echo >&2 "Usage: pcp-push [options]"
echo >&2
echo >&2 "options:"
echo >&2 " -b branch [defaults to current branch]"
echo >&2 " -m don't launch mail client or create pull request"
echo >&2 " -n dryrun"
echo >&2 " -r range [defaults to \$(cat $pushed_sha)..)]"
echo >&2 " -s short format, do not include commit messages"
exit 1
}
case `id -un`
in
kenj)
if which hub >/dev/null
then
hub=hub
elif which git-hub >/dev/null
then
hub=git-hub
else
echo "Arrgh: hub(1)/git-hub(1) is missing. Suggest reinstall from https://github.com/github/hub"
echo "Else for Ubuntu: $ sudo apt install git-hub"
exit 1
fi
;;
esac
dryrun=false
GIT=git
RM=rm
branch=`git branch --show-current`
orig_branch=$branch
tree=origin
short=false
if [ -f $branch.sha ]
then
range=$(cat $branch.sha)..
pushed_sha=$branch.sha
elif [ -f pushed.sha ]
then
range=$(cat pushed.sha)..
pushed_sha=pushed.sha
else
range=''
fi
mail=true
cmdline_branch=false
while getopts "b:mnr:s?" c
do
case $c
in
b)
branch="$OPTARG"
cmdline_branch=true
;;
m) # don't launch mail client or generate pull request
mail=false
;;
n)
dryrun=true
GIT="echo + git"
RM="echo + rm"
;;
r)
range="$OPTARG"
;;
s)
short=true
;;
*)
_usage
# NOTREACHED
esac
done
shift `expr $OPTIND - 1`
[ $# -eq 0 ] || _usage
if [ -z "$range" ]
then
echo "Error: no range from $pushed_sha, so need -r range"
exit 1
fi
unset GIT_EXTERNAL_DIFF
push=`git config remote.origin.url`
case "$push"
in
*github*)
# new school ...
#
;;
*)
echo "Sorry, no recipe to handle repo: $push"
exit 1
;;
esac
changes=true
echo "Changes committed to $push $branch" >/tmp/msg
echo >>/tmp/msg
git shortlog --no-merges --numbered $range >$tmp.tmp
if [ -s $tmp.tmp ]
then
cat $tmp.tmp >>/tmp/msg
else
echo "Nothing to push ..."
changes=false
rm -f /tmp/msg
fi
if $changes
then
git log --no-merges -p $range | diffstat -p1 >>/tmp/msg
if $short
then
:
else
echo >>/tmp/msg
echo "Details ..." >>/tmp/msg
echo >>/tmp/msg
git log --no-merges $range >>/tmp/msg
fi
xclip -sel clip < /tmp/msg
cat /tmp/msg
echo "(all of this for email is in /tmp/msg)"
fi
# even if no changes locally, still push to remote, e.g.
# after git-refresh to pull commits from the remote official
# repo, then these need to go back to the origin for this
# repo
#
rm -f $tmp.y
while true
do
echo -n "Push to $push $branch [y|n|q] (or ctrl+C to abort) "
read ans </dev/tty
if [ -z "$ans" ]
then
:
elif [ "$ans" = y ]
then
touch $tmp.y
break
elif [ "$ans" = n ]
then
break
elif [ "$ans" = q ]
then
echo "Quitting ... $pushed_sha not updated"
exit
fi
echo "Answer the question, bozo!"
done
rm -f $tmp.needpush
if [ -f $tmp.y ]
then
if [ "$branch" != main ]
then
$GIT push -u origin $branch
touch $tmp.needpush
else
# commits _and_ tags ...
#
$GIT push $push
$GIT push --tags $push
# need to get last commit aligned locally and remotely, so that
# HEAD -> main, origin/main, origin/HEAD
#
$GIT pull
fi
fi
# remember last commit that was pushed ...
#
sha=`git log | sed -e 's/commit //' -e 1q`
if $cmdline_branch
then
if $dryrun
then
echo "+ echo $sha >$branch.sha"
else
echo "$sha" >$branch.sha
fi
else
if $dryrun
then
echo "+ echo $sha >pushed.sha"
else
echo "$sha" >pushed.sha
fi
fi
if $mail
then
case `id -un`
in
kenj)
# using hub(1)/git-hub(1) to generate a pull request
#
while true
do
rm -f $tmp.pr
echo -n "Pull request title: [n|q|title] "
read ans </dev/tty
if [ "$ans" = n ]
then
echo "Skipping ... github pull request"
break
elif [ "$ans" = q ]
then
echo "Quitting ... no github pull request generated"
exit
elif [ -n "$ans" ]
then
echo "$ans" >$tmp.pr
echo >>$tmp.pr
cat /tmp/msg >>$tmp.pr
break
else
echo "Answer the question, bozo!"
fi
done
if [ -f $tmp.pr ]
then
if $dryrun
then
echo "+ $hub pull-request -F $tmp.pr"
echo "---- 8< ----"
cat $tmp.pr
else
$hub pull-request -F $tmp.pr
fi
fi
;;
esac
else
if $changes
then
echo "cut-n-paste from /tmp/msg into mail program and send to pcp@group.io"
fi
fi
if [ "$branch" != main ] && $mail
then
# Back to the main branch, but leave the temporary branch to
# allow further commits to be added onto the same Pull Request
# on github
#
$GIT checkout main
# and if we pushed a non-main branch, then also push the main
# branch back to the remote repo
#
if [ -f $tmp.needpush ]
then
$GIT push $push
fi
branch=main
fi
if [ "$branch" != "$orig_branch" ]
then
# put us back to the branch we started from ...
#
$GIT checkout $orig_branch
fi
# may have local git mirror that needs to be updated ...
#
if [ -d $HOME/git-mirror ]
then
here=`pwd`
cd $HOME/git-mirror
for dir in *
do
[ -d "$dir" ] || continue
[ -f "$dir/config" ] || continue
if grep "url = $push" "$dir/config" >/dev/null 2>&1
then
# found repo with url matching the one we've just pushed to
#
cd $dir
echo "Update local $dir git mirror ..."
$GIT fetch
cd ..
fi
done
cd $here
fi
|