#!/usr/bin/env bash set -e usage() { cat >&2 </dev/null 2>&1 \ || fail "The 'gh' CLI tool is not installed; see https://cli.github.com/" gh auth status 2>/dev/null || fail "Not authenticated to github" # Find the last commit that was merged. We will look back in `main` # for other commits from the same PR. # shellcheck disable=SC2016 merge_commit="$( gh api graphql \ -q '.data.repository.pullRequest.timelineItems.nodes[0].commit.oid' \ -F pr_id="$1" \ -f query=' query($pr_id:Int!) { repository(name: "zulip", owner: "zulip") { pullRequest(number:$pr_id) { timelineItems(last:1, itemTypes: [MERGED_EVENT]) { nodes { ... on MergedEvent { commit { oid } } } } } } } ' )" # We cannot trust the "commits" count on the PR, since only part of it # may get merged, or it may have commits squashed during the merge. # Walk backwards on `main` from the merge commit we found, checking # that each of those commits is still associated with the same PR. commit_id="$merge_commit" while true; do # shellcheck disable=SC2016 this_pr="$(gh api graphql -F "commit_id=$commit_id 0" \ --jq '.data.repository.ref.target.history.edges[].node.associatedPullRequests.nodes[].number' \ -f query=' query($commit_id: String!) { repository(owner: "zulip", name:"zulip") { ref(qualifiedName:"main") { target { ... on Commit { history(first:1, after: $commit_id) { edges { node { oid associatedPullRequests(first: 1) { nodes { number } } } } } } } } } }')" if [ "$this_pr" != "$pr_id" ]; then break fi commit_id="$(git rev-parse "$commit_id"~)" done set -x git cherry-pick -x "$commit_id~..$merge_commit"