Skip to content

Commit

Permalink
fix(hack): various fixes & improvements to cherry-pick script (#12714)
Browse files Browse the repository at this point in the history
(cherry picked from commit 7ba20fe)
  • Loading branch information
agilgur5 committed Apr 10, 2024
1 parent 94b3e91 commit c956d70
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 27 deletions.
8 changes: 4 additions & 4 deletions docs/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
Then get a list of commits you may want to cherry-pick:

```bash
./hack/cherry-pick.sh release-3.3 "fix" true
./hack/cherry-pick.sh release-3.3 "chore(deps)" true
./hack/cherry-pick.sh release-3.3 "build" true
./hack/cherry-pick.sh release-3.3 "ci" true
./hack/cherry-pick.sh release-3.3 "fix"
./hack/cherry-pick.sh release-3.3 "chore(deps)"
./hack/cherry-pick.sh release-3.3 "build"
./hack/cherry-pick.sh release-3.3 "ci"
```

To automatically cherry-pick, run the following:
Expand Down
56 changes: 33 additions & 23 deletions hack/cherry-pick.sh
Original file line number Diff line number Diff line change
@@ -1,46 +1,56 @@
#!/usr/bin/env bash
set -eu
# See docs/releasing.md for instructions.
# See ../docs/releasing.md for instructions.

br="$1" # branch name, e.g. release-3.3
branch="$1" # branch name, e.g. release-3.3
commitPrefix="$2" # prefix to use to filter commits, e.g. fix, chore(deps), build, ci
# whether this is dry-run. If set to `true`, this script will only print out the list
# of commits. Otherwise, this script will automatically cherry-pick the commits to the branch.
dryRun="$3"
# If dryRun is unset or `true`, only print the list of commits to be cherry-picked.
# Otherwise, cherry-pick the commits to the specified branch.
dryRun="${3:-"true"}"

# unfortunately, cherry-picking to another branch is not possible, so error out if not on the branch (c.f. https://stackoverflow.com/q/13878904/3431180)
curr_branch=$(git rev-parse --abbrev-ref HEAD)
if [[ "$curr_branch" != "$branch" ]]; then
echo "Current branch is '$curr_branch', but trying to cherry-pick to branch '$branch'. You must have branch '$branch' checked out in order to cherry-pick"
exit 1
fi

commitGrepPattern="^${commitPrefix}(*.*)*:.*(#"

# find the branch point
base=$(git merge-base "$br" main)
base=$(git merge-base "$branch" main)

# extract the PRs from stdin
prNo() {
set -eu
getPRNum() {
cat | sed "s|.*(\(#[0-9]*\))|\1|"
}

# list the PRs on each branch
prs() {
set -eu
git log --format="%s" --grep "${commitGrepPattern}" "$1...$2" | prNo | sort > "/tmp/$2"
getPRs() {
git log --format="%s" --grep "${commitGrepPattern}" "$1...$2" | getPRNum | sort > "/tmp/$2"
}

prs "$base" "$br"
prs "$base" main
getPRs "$base" "$branch"
getPRs "$base" main

# find PRs added to main
diff "/tmp/$br" /tmp/main | grep "^> " | cut -c 3- > /tmp/prs
diff "/tmp/$branch" /tmp/main | grep "^> " | cut -c 3- > /tmp/prs

# print all the commits that need cherry-picking
git log --oneline --grep "${commitGrepPattern}" "$base...main" | while read -r m; do
git log --oneline --grep "${commitGrepPattern}" "$base...main" | tac | while read -r m; do
if ! grep -q "$(echo "$m" | getPRNum)" /tmp/prs ; then
continue
fi

if [[ "$dryRun" == "true" ]]; then
grep -q "$(echo "$m" | prNo)" /tmp/prs && echo "$m"
else
commit=$(grep -q "$(echo "$m" | prNo)" /tmp/prs && echo "${m:0:9}")
echo "cherry-picking: $commit"
if ! git cherry-pick "$commit"; then
echo "failed to cherry-pick $commit"
git cherry-pick --abort
fi
echo "$m"
continue
fi

commit=${m:0:9}
echo "cherry-picking: $commit"
if ! git cherry-pick "$commit" -x -Xpatience ; then
echo "failed to cherry-pick $commit"
git cherry-pick --abort
fi
done

0 comments on commit c956d70

Please sign in to comment.