Merge pull request #11122 from zmerlynn/multi-pick

hack/cherry_pick_pull.sh: Allow multiple pulls
This commit is contained in:
Tim Hockin 2015-07-13 10:17:14 -07:00
commit 2ad0774562
2 changed files with 55 additions and 41 deletions

View File

@ -8,7 +8,7 @@ Kubernetes projects.
Any contributor can propose a cherry pick of any pull request, like so: Any contributor can propose a cherry pick of any pull request, like so:
``` ```
hack/cherry_pick_pull.sh 98765 upstream/release-3.14 hack/cherry_pick_pull.sh upstream/release-3.14 98765
``` ```
This will walk you through the steps to propose an automated cherry pick of pull This will walk you through the steps to propose an automated cherry pick of pull

View File

@ -28,12 +28,13 @@ cd "${KUBE_ROOT}"
declare -r STARTINGBRANCH=$(git symbolic-ref --short HEAD) declare -r STARTINGBRANCH=$(git symbolic-ref --short HEAD)
declare -r REBASEMAGIC="${KUBE_ROOT}/.git/rebase-apply" declare -r REBASEMAGIC="${KUBE_ROOT}/.git/rebase-apply"
if [[ "$#" -ne 2 ]]; then if [[ "$#" -lt 2 ]]; then
echo "${0} <pr-number> <remote branch>: cherry pick <pr> onto <remote branch> and leave instructions for proposing pull request" echo "${0} <remote branch> <pr-number>...: cherry pick one or more <pr> onto <remote branch> and leave instructions for proposing pull request"
echo "" echo ""
echo " Checks out <remote branch> and handles the cherry-pick of <pr> for you." echo " Checks out <remote branch> and handles the cherry-pick of <pr> (possibly multiple) for you."
echo " Example:" echo " Examples:"
echo " $0 12345 upstream/release-3.14" echo " $0 upstream/release-3.14 12345 # Cherry-picks PR 12345 onto upstream/release-3.14 and proposes that as a PR."
echo " $0 upstream/release-3.14 12345 56789 # Cherry-picks PR 12345, then 56789 and proposes the combination as a single PR."
exit 2 exit 2
fi fi
@ -47,8 +48,14 @@ if [[ -e "${REBASEMAGIC}" ]]; then
exit 1 exit 1
fi fi
declare -r PULL="${1}" declare -r BRANCH="$1"
declare -r BRANCH="${2}" shift 1
declare -r PULLS=( "$@" )
function join { local IFS="$1"; shift; echo "$*"; }
declare -r PULLDASH=$(join - "${PULLS[@]/#/\#}") # Generates something like "#12345-#56789"
declare -r PULLSUBJ=$(join " " "${PULLS[@]/#/\#}") # Generates something like "#12345 #56789"
echo "+++ Updating remotes..." echo "+++ Updating remotes..."
git remote update git remote update
@ -58,11 +65,8 @@ if ! git log -n1 --format=%H "${BRANCH}" >/dev/null 2>&1; then
exit 1 exit 1
fi fi
echo "+++ Downloading patch to /tmp/${PULL}.patch (in case you need to do this again)" declare -r NEWBRANCHREQ="automated-cherry-pick-of-${PULLDASH}" # "Required" portion for tools.
declare -r NEWBRANCH="$(echo ${NEWBRANCHREQ}-${BRANCH} | sed 's/\//-/g')"
curl -o "/tmp/${PULL}.patch" -sSL "https://github.com/GoogleCloudPlatform/kubernetes/pull/${PULL}.patch"
declare -r NEWBRANCH="$(echo automated-cherry-pick-of-#${PULL}-on-${BRANCH} | sed 's/\//-/g')"
declare -r NEWBRANCHUNIQ="${NEWBRANCH}-$(date +%s)" declare -r NEWBRANCHUNIQ="${NEWBRANCH}-$(date +%s)"
echo "+++ Creating local branch ${NEWBRANCHUNIQ}" echo "+++ Creating local branch ${NEWBRANCHUNIQ}"
@ -84,35 +88,39 @@ trap return_to_kansas EXIT
git checkout -b "${NEWBRANCHUNIQ}" "${BRANCH}" git checkout -b "${NEWBRANCHUNIQ}" "${BRANCH}"
cleanbranch="${NEWBRANCHUNIQ}" cleanbranch="${NEWBRANCHUNIQ}"
echo
echo "+++ About to attempt cherry pick of PR. To reattempt:"
echo " $ git am -3 /tmp/${PULL}.patch"
echo
gitamcleanup=true gitamcleanup=true
git am -3 "/tmp/${PULL}.patch" || { for pull in "${PULLS[@]}"; do
conflicts=false echo "+++ Downloading patch to /tmp/${pull}.patch (in case you need to do this again)"
while unmerged=$(git status --porcelain | grep ^U) && [[ -n ${unmerged} ]] \ curl -o "/tmp/${pull}.patch" -sSL "https://github.com/GoogleCloudPlatform/kubernetes/pull/${pull}.patch"
|| [[ -e "${REBASEMAGIC}" ]]; do echo
conflicts=true # <-- We should have detected conflicts once echo "+++ About to attempt cherry pick of PR. To reattempt:"
echo echo " $ git am -3 /tmp/${pull}.patch"
echo "+++ Conflicts detected:" echo
echo git am -3 "/tmp/${pull}.patch" || {
(git status --porcelain | grep ^U) || echo "!!! None. Did you git am --continue?" conflicts=false
echo while unmerged=$(git status --porcelain | grep ^U) && [[ -n ${unmerged} ]] \
echo "+++ Please resolve the conflicts in another window (and remember to 'git add / git am --continue')" || [[ -e "${REBASEMAGIC}" ]]; do
read -p "+++ Proceed (anything but 'y' aborts the cherry-pick)? [y/n] " -r conflicts=true # <-- We should have detected conflicts once
echo echo
if ! [[ "${REPLY}" =~ ^[yY]$ ]]; then echo "+++ Conflicts detected:"
echo "Aborting." >&2 echo
(git status --porcelain | grep ^U) || echo "!!! None. Did you git am --continue?"
echo
echo "+++ Please resolve the conflicts in another window (and remember to 'git add / git am --continue')"
read -p "+++ Proceed (anything but 'y' aborts the cherry-pick)? [y/n] " -r
echo
if ! [[ "${REPLY}" =~ ^[yY]$ ]]; then
echo "Aborting." >&2
exit 1
fi
done
if [[ "${conflicts}" != "true" ]]; then
echo "!!! git am failed, likely because of an in-progress 'git am' or 'git rebase'"
exit 1 exit 1
fi fi
done }
done
if [[ "${conflicts}" != "true" ]]; then
echo "!!! git am failed, likely because of an in-progress 'git am' or 'git rebase'"
exit 1
fi
}
gitamcleanup=false gitamcleanup=false
if git remote -v | grep ^origin | grep GoogleCloudPlatform/kubernetes.git; then if git remote -v | grep ^origin | grep GoogleCloudPlatform/kubernetes.git; then
@ -123,7 +131,10 @@ if git remote -v | grep ^origin | grep GoogleCloudPlatform/kubernetes.git; then
echo echo
echo "where REMOTE is your personal fork (maybe 'upstream'? Consider swapping those.)." echo "where REMOTE is your personal fork (maybe 'upstream'? Consider swapping those.)."
echo "Then propose ${NEWBRANCH} as a pull against ${BRANCH} (NOT MASTER)." echo "Then propose ${NEWBRANCH} as a pull against ${BRANCH} (NOT MASTER)."
echo "Use this exact subject: 'Automated cherry pick of #${PULL}' and include a justification." echo "Use this subject: 'Automated cherry pick of ${PULLSUBJ}' and include a justification."
echo ""
echo "Note: the tools actually scrape the branch name you just pushed, so don't worry about"
echo "the subject too much, but DO keep at least ${NEWBRANCHREQ} in the remote branch name."
cleanbranch="" cleanbranch=""
exit 0 exit 0
fi fi
@ -143,5 +154,8 @@ git push origin -f "${NEWBRANCHUNIQ}:${NEWBRANCH}"
echo echo
echo "+++ Now you must propose ${NEWBRANCH} as a pull against ${BRANCH} (NOT MASTER)." echo "+++ Now you must propose ${NEWBRANCH} as a pull against ${BRANCH} (NOT MASTER)."
echo " You must use this exact subject: 'Automated cherry pick of #${PULL}' and include a justification." echo " Use this subject: 'Automated cherry pick of ${PULLSUBJ}' and include a justification."
echo ""
echo " Note: the tools actually scrape the branch name you just pushed, so don't worry about"
echo " the subject too much, but DO keep at least ${NEWBRANCHREQ} in the remote branch name."
echo echo