-
-
Save ikhoon/9e960ea6466e9a73ebafc69e73196ff7 to your computer and use it in GitHub Desktop.
git-checkout-pr.sh - fetches a Git pull request from the remote and creates a local branch for it
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -Eeuo pipefail | |
log() { | |
echo -en '\033[1;32m' | |
echo -n "$@" | |
echo -e '\033[0m' | |
} | |
choice() { | |
if [[ $# -gt 0 ]]; then | |
# Use the first keyword as a serach keyword to minimize the list results | |
SEARCH=$1 | |
else | |
SEARCH='' | |
fi | |
# gh pr list command always terminates with exit code 0 in a non-interactive | |
# environment. As a workaround, we check whether its output is empty | |
# to detect if the command was successful or not. | |
PR_CHOICES="$( | |
gh pr list --json number,title,author --limit 50 --search "is:open sort:updated-desc $SEARCH" | | |
jq -r '.[] | "\u001b[1m#\(.number)\u001b[0m \(.title) \u001b[0;32m@\(.author.login)\u001b[0m"' | |
)" | |
if [[ -z "$PR_CHOICES" ]]; then | |
echo 'Failed to list the pull requests.' | |
echo 'Please make sure `gh` command is configured properly.' | |
exec gh pr list | |
fi | |
PR_LENGTH="$(echo "$PR_CHOICES" | wc -l)" | |
if [[ "$PR_LENGTH" =~ ^[[:space:]]*1[[:space:]]* ]]; then | |
# The gh pr list command found only one result. | |
# Removing ANSI color codes from text | |
PR_CHOICE=$(echo $PR_CHOICES | sed -e 's/\x1b\[[0-9;]*m//g') | |
else | |
PR_CHOICE="$( | |
echo -n "$PR_CHOICES" | | |
fzf --ansi --prompt='Choose the pull request to check out: ' | |
)" | |
fi | |
if [[ "$PR_CHOICE" =~ (^#([0-9]+) ) ]]; then | |
PR_ID="${BASH_REMATCH[2]}" | |
else | |
echo 'Failed to parse the choice:' | |
echo | |
echo " $PR_CHOICE" | |
echo | |
exit 1 | |
fi | |
} | |
case $# in | |
0) | |
choice | |
;; | |
1) | |
if [[ $1 =~ ^[0=9]+$ ]]; then | |
PR_ID="$1" | |
else | |
choice $1 | |
fi | |
;; | |
*) | |
echo "Usage: $0 [<pull request ID> or <search keyword>]" 1>&2 | |
exit 1 | |
;; | |
esac | |
PR_INFO="$(gh pr view "$PR_ID" --json 'headRepositoryOwner,headRefName,url')" | |
PR_AUTHOR="$(echo "$PR_INFO" | jq -r '.headRepositoryOwner.login')" | |
PR_BRANCH="$(echo "$PR_INFO" | jq -r '.headRefName')" | |
PR_URL="$(echo "$PR_INFO" | jq -r '.url')" | |
LOCAL_BRANCH="pr-$PR_ID-$PR_AUTHOR-$PR_BRANCH" | |
PR_ID_HYPERLINK="$(echo -e "\033]8;;$PR_URL\007#$PR_ID\033]8;;\007")" | |
if git branch --list --format='%(refname:short)' | grep -qF "$LOCAL_BRANCH"; then | |
if [[ "$(git branch --show-current)" == "$LOCAL_BRANCH" ]]; then | |
echo "You are already on the branch $LOCAL_BRANCH for $PR_ID_HYPERLINK." | |
else | |
log "You already have the branch $LOCAL_BRANCH for $PR_ID_HYPERLINK; switching to the local branch .." | |
git checkout "$LOCAL_BRANCH" | |
fi | |
exit 1 | |
else | |
log "Checking out the pull request $PR_ID_HYPERLINK into $LOCAL_BRANCH .." | |
gh pr checkout "$PR_ID" -b "pr-$PR_ID-$PR_AUTHOR-$PR_BRANCH" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment