If you use GitHub much, you'll likely find yourself having to repeatedly use the web interface to raise pull requests. The web interface is great and all, but it can really take you out of your flow if you're used to creating branches, rebasing, pushing, and pulling from the command line!
Luckily GitHub has a REST API that you can use to create pull requests instead, and a nice command line wrapper to invoke it called Hub! Hub wraps the git
command line tool - effectively adding extra commands you can invoke from the command line. Once it's installed (and aliased) you'll be able to call:
> git pull-request
and a new pull request will be created in your repository:
If you're someone who likes using the command line, this can really help streamline your workflow.
Installing Hub
Hub is available on GitHub so you can download binaries, or install it from source. As I use chocolatey on my dev machine, I chose to install Hub using chocolatey by running the following from an administrative powershell:
> choco install hub
Chocolatey will download and install hub into its standard installation folder (C:\ProgramData\chocolatey by default). As this folder should be in your PATH, you can type hub version
from the command line and you should get back something similar to:
> hub version
git version 2.15.1.windows.2
hub version 2.2.9
That's it, you're good to go. The first time you use Hub to create a pull request (PR), it will prompt you for your GitHub username and password.
Creating a pull request with Hub
Hub is effectively an extension of the git
command line, so it can do everything git
does, and just adds some helper GitHub
methods on top. Anything you can do with git
, you can do with hub
.
You can view all the commands available by simply typing hub
into the command line. As hub
is a wrapper for git
it starts by displaying the git
help message:
> hub
usage: git [--version] [--help] [-C <path>] [-c name=value]
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p | --paginate | --no-pager] [--no-replace-objects] [--bare]
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
<command> [<args>]
These are common Git commands used in various situations:
start a working area (see also: git help tutorial)
clone Clone a repository into a new directory
init Create an empty Git repository or reinitialize an existing one
...
At the bottom, hub
lists the GitHub specific commands available to you:
These GitHub commands are provided by hub:
pull-request Open a pull request on GitHub
fork Make a fork of a remote repository on GitHub and add as remote
create Create this repository on GitHub and add GitHub as origin
browse Open a GitHub page in the default browser
compare Open a compare page on GitHub
release List or create releases (beta)
issue List or create issues (beta)
ci-status Show the CI status of a commit
As you can see, there's a whole bunch of useful commands there. The one I'm interested in is pull-request
.
Lets imagine we have already checked out a repository we own, and we have created a branch to work on a feature, feature-37
:
Before we can create a PR, we need to push our branch to the server:
> git push origin -u feature-37
To create the PR, we use hub
. This will open up your configured text editor to enter a message for the PR (I use Notepad++) . In the comments you can see the commit messages for the branch, or if your PR only has a single commit (as in this example), hub
will handily fill the message in for you, just as it does in the web interface:
As you can see from the comments in the screenshot, the first line of your message forms the PR title, and the remainder forms the description of the PR. After saving your message, hub
spits out the URL for your PR on GitHub. Follow that link, and you can see your shiny new PR ready and waiting approval:
Hub can do lots more than just create pull requests, but for me that's the killer feature I use everyday. If you use more features, then you may want to consider aliasing your hub
command to git
as it suggests in the docs.
Aliasing hub
as git
As I mentioned earlier, hub
is a wrapper around git
that provides some handy extra tweaks. It even enhances some of the standard git
commands: it can expand partial URLs in a git clone
to be github.com addresses for example:
> hub clone andrewlock/test
# expands to
git clone git://github.com/andrewlock/test.git
If you find yourself using the hub
command a lot, then you might want to consider aliasing your git
command to actually use Hub instead. That means you can just do
> git clone andrewlock/test
for example, without having to think about which commands are hub
specific, and which are available in git
. Adding an alias is safe to do, you're not modifying the underlying git
program or anything, so don't worry about that.
If you're using PowerShell, you can add the alias to your profile by running:
> Add-Content $PROFILE "`nSet-Alias git hub"
and then restarting your session. For troubleshooting and other scripts see https://github.com/github/hub#aliasing.
Streamlining PR creation with a git
alias
I love how much time hub
has saved me by keeping my hands on the keyboard, but there's one thing that was annoying me: having to run git push
before opening the PR. I'm a big fan of Git aliases, so I decided to create an alias called pr
that does two things: push, and create a pull request.
If you're new to git aliases, I highly recommend checking out this post from Phil Haack. He explains what aliases are, why you want them, and gives a bunch of really useful aliases to get started.
You can create aliases directly from the command line with git
, but for all but the simplest ones I like to edit the .gitconfig file directly. To open your global .gitconfig for editing, use
> git config --global --edit
This will popup your editor of choice, and allow you to edit to your heart's content. Locate the [alias]
section of your config file (or if it doesn't exist, add it), and enter the following:
[alias]
pr="!f() { \
BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD); \
git push -u origin $BRANCH_NAME; \
hub pull-request; \
};f "
This alias uses the slightly more complex script format that creates a function and executes it immediately. In that function, we do three things:
BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD);
- Get the name of the current branch fromgit
and store it in a variable,BRANCH_NAME
git push -u origin $BRANCH_NAME;
- Push the current branch to the remoteorigin
, and associate it with the remote branch of the same namehub pull-request
- Create the pull request usinghub
To use the alias, simply check out the branch you wish to create a PR for and run:
> git pr
This will push the branch if necessary and create the pull request for you, all in one (prompting you for the PR title in your editor as usual).
> git pr
Counting objects: 11, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (11/11), 1012 bytes | 1012.00 KiB/s, done.
Total 11 (delta 9), reused 0 (delta 0)
remote: Resolving deltas: 100% (9/9), completed with 7 local objects.
To https://github.com/andrewlock/NetEscapades.AspNetCore.SecurityHeaders.git
* [new branch] feature-37 -> feature-37
Branch 'feature-37' set up to track remote branch 'feature-37' from 'origin'.
https://github.com/andrewlock/NetEscapades.AspNetCore.SecurityHeaders/pull/40
Note, there is code in the Hub GitHub repository indicating that
hub pr
is going to be a feature that allows you to check-out a given PR. If that's the case this alias may break, so I'll keep an eye out!
Summary
Hub is a great little wrapper from GitHub that just simplifies some of the things I do many times a day. If you find it works for you, check it out on GitHub - it's written in Go and I've no doubt they'd love to have more contributors.