mirror of https://github.com/zulip/zulip.git
103 lines
2.4 KiB
Bash
Executable File
103 lines
2.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -e
|
|
|
|
usage() {
|
|
cat >&2 <<EOF
|
|
usage: $0 PULL_REQUEST_ID COMMIT_COUNT [REMOTE]
|
|
|
|
Fetch the given GitHub pull request branch and backport it to
|
|
the current branch using 'git cherry-pick -x'.
|
|
|
|
Typical usage is:
|
|
git fetch upstream
|
|
git checkout -b 8.x upstream/8.x
|
|
$0 FIRST_PR_ID
|
|
$0 SECOND_PR_ID
|
|
git push origin +HEAD:backport-changes
|
|
EOF
|
|
exit 1
|
|
}
|
|
|
|
pr_id="$1"
|
|
|
|
if [ -z "$pr_id" ]; then
|
|
usage
|
|
fi
|
|
|
|
fail() {
|
|
echo "$1"
|
|
exit 1
|
|
}
|
|
|
|
type gh >/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"
|