I want to be able to type git open-pr-github
and have my browser open to the GitHub URL to create a Pull Request (PR) for my current branch on the current project I’m working on. Here is how I built this.
Git Alias
This alias can be added to your ~/.gitconfig
file. The fastest way to add this is to run the following from the command line.
git config --global alias.open-pr-github '!f() { open "$(git ls-remote --get-url $(git config --get branch.$(git branch --show-current).remote) | sed '"'"'s|git@github.com:\(.*\)$|https://github.com/\1|'"'"' | sed '"'"'s|\.git$||'"'"')/compare/$(git config --get branch.$(git branch --show-current).merge | cut -d '/' -f 3-)?expand=1"; }; f'
Git Alias in Git Config
Instead of running the command above, you can manually add the following to your ~/.gitconfig
file.
[alias]
open-pr-github = "!f() { \
open \"$(git ls-remote --get-url $(git config --get branch.$(git branch --show-current).remote) \
| sed 's|git@github.com:\\(.*\\)$|https://github.com/\\1|' \
| sed 's|\\.git$||'; \
)/compare/$(\
git config --get branch.$(git branch --show-current).merge | cut -d '/' -f 3- \
)?expand=1\"; \
}; f"
The resulting alias behaves the same, the only difference is this manually added version is broken up over multiple lines for readability.
Pieces of the Puzzle
Get Current Local Branch Name
# Get current branch name
# e.g. "feat/add-open-github-pr"
git branch --show-current
Get Remote Name for Current Branch
# Get remote for the current branch (e.g. "origin")
# Note: this will return nothing if the current branch is not tracking a remote branch.
# See https://git-scm.com/docs/git-config#Documentation/git-config.txt-branchltnamegtremote
git config --get branch.$(git branch --show-current).remote
Get Remote Branch Name Being Tracked
# Get branch name on remote local branch is tracking
# e.g. "refs/heads/feat/add-open-github-pr"
# See https://git-scm.com/docs/git-config#Documentation/git-config.txt-branchltnamegtmerge
git config --get branch.$(git branch --show-current).merge
Get Trim “refs/heads”
echo "refs/heads/feat/add-open-github-pr" | cut -d '/' -f 3-
Get Trimmed Remote Branch Name Being Tracked
# Get trimmed branch name on remote local branch is tracking
# i.e. remove the leading "refs/heads"
# e.g. "feat/add-open-github-pr"
git config --get branch.$(git branch --show-current).merge | cut -d '/' -f 3-
Note on all of my projects the trimmed remote branch name being tracked is the same as your local branch name (e.g. feat/add-open-github-pr
), however you can track a remote branch with a different name (though this just seems like asking for trouble) so we jump through these extra hoops to ensure we have the correct remote branch name
Remote Remote URL
# Get the URL for the remote "origin"
# e.g. "git@github.com:ironcodestudio/ironcode-git-enhancements.git" (SSH)
# e.g. "https://github.com/ironcodestudio/ironcode-git-enhancements.git" (HTTPS)
git ls-remote --get-url origin
Note: these remote URLs come in two different formats, SSH and HTTPS
Get Remote URL Associated with the Current Branch
# Get the URL for the remote associated with the current branch
git ls-remote --get-url $(git config --get branch.$(git branch --show-current).remote)
Normalize SSH style URL to HTTPS Style
Since the remote URL can be in two different formats (SSH or HTTPS), we apply a regular expression to normalize the URL to HTTPS style.
echo "git@github.com:ironcodestudio/ironcode-git-enhancements.git" | sed 's|^.*github.com[:/]\(.*\)$|https://\1|'
echo "https://github.com/ironcodestudio/ironcode-git-enhancements.git" | sed 's|^.*github.com[:/]\(.*\)$|https://\1|'
# both result in the same
https://github.com/ironcodestudio/ironcode-git-enhancements.git
Normalize Current Remote URL
# Normalize SSH style URL to HTTPS style
# (if the URL is already HTTPS style, make no changes)
git ls-remote --get-url $(git config --get branch.$(git branch --show-current).remote) \
| sed 's|git@github.com:\(.*\)$|https://github.com/\1|'
Transform an HTTPS Style Remote URL to Browser URL
# Transform HTTPS URL to browser URL
# Remove .git from end of HTTPS style URL
echo "https://github.com/ironcodestudio/ironcode-git-enhancements.git" | sed 's|\.git$||'
Transform Remote URL (SSH or HTTPS) to Browser URL
echo "git@github.com:ironcodestudio/ironcode-git-enhancements.git" | sed 's|git@github.com:\(.*\)$|https://github.com/\1|'
echo "https://github.com/ironcodestudio/ironcode-git-enhancements.git" | sed 's|git@github.com:\(.*\)$|https://github.com/\1|'
# Both output the same
# https://github.com/ironcodestudio/ironcode-git-enhancements.git
Put the Pieces Together to Output the Browser URL
echo "$(git ls-remote --get-url $(git config --get branch.$(git branch --show-current).remote) \
| sed 's|git@github.com:\(.*\)$|https://github.com/\1|' \
| sed 's|\.git$||')/compare/$(git config --get branch.$(git branch --show-current).merge | cut -d '/' -f 3-)?expand=1"
Open Instead of Echo
open "$(git ls-remote --get-url $(git config --get branch.$(git branch --show-current).remote) \
| sed 's|git@github.com:\(.*\)$|https://github.com/\1|' \
| sed 's|\.git$||')/compare/$(git config --get branch.$(git branch --show-current).merge | cut -d '/' -f 3-)?expand=1"
Inspired by
Inspired by this Gist by rpavolovs and the git-open project by Paul Irish.
How this Differs
The solution here differs from these other solutions in that this solution has all of the code contained within the ~/.gitconfig
file.
Update to Accept Target Branch
This command has been updated to accept a <target>
branch.
git open-pr-github my-branch
will now open a PR into my-branch
instead of into the repo’s default branch.
See GitHub PR: Add optional target branch argument to “open-pr-github” alias.
This is one of those examples of how far we’ll go to avoid a GUI lol. (Kidding!) I totally love this. I only use git on the cli and I’m definitely going to steal this.
+ 100 points for using sed.
Ha ha, yeah
sed
is definitely one of those tools I’m still learning but I see a ton of potential in it.Oh, and you used an animated gif! Aubrey is having a very good influence on you.