Skip to content

Instantly share code, notes, and snippets.

@lobsterkatie
Last active June 13, 2023 20:23
Show Gist options
  • Save lobsterkatie/d90b135119c8b11860e6bd0608a4d55d to your computer and use it in GitHub Desktop.
Save lobsterkatie/d90b135119c8b11860e6bd0608a4d55d to your computer and use it in GitHub Desktop.
bash code to open a PR
# 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