| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 | #!/usr/bin/env bash# Land a pull request# Creates a PR-### branch, pulls the commits, opens up an interactive rebase to# squash, and then annotates the commit with the changelog goobers## Usage:#   pr <url|number> [<upstream remote>=origin]main () {  if [ "$1" = "finish" ]; then    shift    finish "$@"    return $?  fi  local url="$(prurl "$@")"  local num=$(basename $url)  local prpath="${url#git@github.com:}"  local repo=${prpath%/pull/$num}  local prweb="https://github.com/$prpath"  local root="$(prroot "$url")"  local api="https://api.github.com/repos/${repo}/pulls/${num}"  local user=$(curl -s $api | json user.login)  local ref="$(prref "$url" "$root")"  local curhead="$(git show --no-patch --pretty=%H HEAD)"  local curbranch="$(git rev-parse --abbrev-ref HEAD)"  local cleanlines  IFS=$'\n' cleanlines=($(git status -s -uno))  if [ ${#cleanlines[@]} -ne 0 ]; then    echo "working dir not clean" >&2    IFS=$'\n' echo "${cleanlines[@]}" >&2    echo "aborting PR merge" >&2  fi  # ok, ready to rock  branch=PR-$num  if [ "$curbranch" == "$branch" ]; then    echo "already on $branch, you're on your own" >&2    return 1  fi  me=$(git config github.user || git config user.name)  if [ "$me" == "" ]; then    echo "run 'git config --add github.user <username>'" >&2    return 1  fi  exists=$(git show --no-patch --pretty=%H $branch 2>/dev/null)  if [ "$exists" == "" ]; then    git fetch origin pull/$num/head:$branch    git checkout $branch  else    git checkout $branch    git pull --rebase origin pull/$num/head  fi  git rebase -i $curbranch # squash and test  if [ $? -eq 0 ]; then    finish "${curbranch}"  else    echo "resolve conflicts and run: $0 finish "'"'${curbranch}'"'  fi}# add the PR-URL to the last commit, after squashingfinish () {  if [ $# -eq 0 ]; then    echo "Usage: $0 finish <branch> (while on a PR-### branch)" >&2    return 1  fi  local curbranch="$1"  local ref=$(cat .git/HEAD)  local prnum  case $ref in    "ref: refs/heads/PR-"*)      prnum=${ref#ref: refs/heads/PR-}      ;;    *)      echo "not on the PR-## branch any more!" >&2      return 1      ;;  esac  local me=$(git config github.user || git config user.name)  if [ "$me" == "" ]; then    echo "run 'git config --add github.user <username>'" >&2    return 1  fi  set -x  local url="$(prurl "$prnum")"  local num=$prnum  local prpath="${url#git@github.com:}"  local repo=${prpath%/pull/$num}  local prweb="https://github.com/$prpath"  local root="$(prroot "$url")"  local api="https://api.github.com/repos/${repo}/pulls/${num}"  local user=$(curl -s $api | json user.login)  local lastmsg="$(git log -1 --pretty=%B)"  local newmsg="${lastmsg}PR-URL: ${prweb}Credit: @${user}Close: #${num}Reviewed-by: @${me}"  git commit --amend -m "$newmsg"  git checkout $curbranch  git merge PR-${prnum} --ff-only  set +x}prurl () {  local url="$1"  if [ "$url" == "" ] && type pbpaste &>/dev/null; then    url="$(pbpaste)"  fi  if [[ "$url" =~ ^[0-9]+$ ]]; then    local us="$2"    if [ "$us" == "" ]; then      us="origin"    fi    local num="$url"    local o="$(git config --get remote.${us}.url)"    url="${o}"    url="${url#(git:\/\/|https:\/\/)}"    url="${url#git@}"    url="${url#github.com[:\/]}"    url="${url%.git}"    url="https://github.com/${url}/pull/$num"  fi  url=${url%/commits}  url=${url%/files}  url="$(echo $url | perl -p -e 's/#issuecomment-[0-9]+$//g')"  local p='^https:\/\/github.com\/[^\/]+\/[^\/]+\/pull\/[0-9]+$'  if ! [[ "$url" =~ $p ]]; then    echo "Usage:"    echo "  $0 <pull req url>"    echo "  $0 <pull req number> [<remote name>=origin]"    type pbpaste &>/dev/null &&      echo "(will read url/id from clipboard if not specified)"    exit 1  fi  url="${url/https:\/\/github\.com\//git@github.com:}"  echo "$url"}prroot () {  local url="$1"  echo "${url/\/pull\/+([0-9])/}"}prref () {  local url="$1"  local root="$2"  echo "refs${url:${#root}}/head"}main "$@"
 |