Last active
June 13, 2023 20:23
-
-
Save lobsterkatie/d90b135119c8b11860e6bd0608a4d55d to your computer and use it in GitHub Desktop.
bash code to open a PR
This file contains 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
# NOTE: Apologies to anyone who actually speaks bash, because I'm sure all the comments | |
# here feel annoyingly obvious. As someone who writes bash once in a blue moon, I find it | |
# helpful to leave myself extensive hints so future-me has any clue what current-me | |
# has written. | |
# This code lives in my `.zshrc` and makes it so that I can run `git push && pr` and a new | |
# PR will open in my browser. Notably, it uses `origin` as a base, which solves the problem | |
# discussed in https://github.com/orgs/community/discussions/11729. | |
# get origin's default branch and then strip off the "origin/" prefix | |
alias get_main_branch='git rev-parse --abbrev-ref origin/HEAD | sed s/"origin\/"//' | |
# NOTE: This accounts for detached heads because I also use it to set my prompt. | |
# If you're just using it for `get_compare_url`, you can just use | |
# `git rev-parse --abbrev-ref HEAD` instead of this function. | |
function get_current_branch() { | |
# If we're in a git repo, HEAD will resolve to something and the exit | |
# status of git rev-parse will be 0 (good); otherwise, it will be 128 | |
# (bad). Negate that so that if we're not good (not in a git repo), we | |
# can bail. (The parens run the command in a sub-shell, and the &> sends | |
# both stdout and stderr to /dev/null.) | |
if ! (git rev-parse HEAD &>/dev/null); then | |
return | |
fi | |
# so now we know were in a repo, so get the branch name (the $() captures | |
# the stdout of the command inside the parens) | |
local git_branch=$(git rev-parse --abbrev-ref HEAD) | |
# If we've checked out a particular commit, the HEAD has no other --abrev-ref | |
# besides "HEAD." In that case, change the "branch name" to say so. (The [[ ]] | |
# are for capturing the boolean value of a statement.) | |
if [[ $git_branch == "HEAD" ]]; then | |
# in a `git log` command, -n <num> shows you only the most recent <num> | |
# commits, and in the format string, "%h" is the short form of the | |
# commit sha | |
git_branch="Detached HEAD at $(git log -n 1 --format="%h")" | |
fi | |
# since you can't return anything from a bash/zsh function, echo the result | |
# and then capture it on the other end with $() | |
echo $git_branch | |
} | |
function get_repo_url() { | |
#get names of remotes - should be "origin" - and take the first one in case there's more than one | |
#(head -n <x> gives you the first <x> lines of output) | |
local remote_name=$(git remote | head -n 1) | |
#url should be of the form https://github.com/<gh-org-name>/<gh-repo-name>.git | |
#use sed to remove the .git (-E makes sed use "extended" regexes) | |
#(because git prints to stdout, we don't need to echo here) | |
git remote get-url ${remote_name} | sed -E s/\\.git// | |
} | |
function get_compare_url() { | |
# this assumes the branch is of the form `xyz` or `abc/xyz`, and returns `xyz` in either case | |
local branch_basename=$(basename $(get_current_branch)) | |
local repo_url_base=$(get_repo_url) | |
echo "${repo_url_base}/compare/$(get_main_branch)...${branch_basename}" | |
} | |
function pr() { | |
local branch_name=$(git rev-parse --abbrev-ref HEAD) | |
# see if a PR already exists. If it does, it should be listed in `.git/config` under `branch.<branch-name>.github-pr-owner-number`, | |
# in the form `<gh-org>#<gh-repo>#<PR-number>`. Pipe that to sed (using `-E` to be able to use regular regexes) to pull off the first | |
# two `<...>#` segments, leaving just the number. | |
local PR_num=$(git config branch.${branch_name}.github-pr-owner-number | sed -E 's/([^#]+#){2}//') | |
if [[ -n "$PR_num" ]]; then | |
local pr_url=$(get_repo_url)/pull/$PR_num | |
echo "\nOpening existing PR: $pr_url." | |
open $pr_url | |
return | |
fi | |
# using the "${repo_url_base}/pull/new/${branch_name}" url recommended in the | |
# git output after running `git push`` just gets you redirected to | |
# "${repo_url_base}/compare/${branch_name}?expand=1", so we can reuse the | |
# url we computed for the `compare` function above | |
echo "\nNo existing PR found. Opening a new one." | |
open "$(get_compare_url)?expand=1" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment