Real Iterations

The technical blog of front end developer Réal Provencher

hub+git makes Github better

May 11, 2015 | 7 Minute Read

Git is an incredible version control system for projects both large and small, and Github is a perfect companion for hosting repositories. But Git was never designed to be used with Github; the opposite is true. There is a tool called Hub which gives Git a whole new set of commands specifically targeted at Github users, and I'll show you how to set it up so you won't even realize you're using it until you try to use someone else's workstation without it.

This post will have three short parts:

  1. Going over the hub commands
  2. Installing hub and setting a command line alias
  3. My .gitconfig aliases for hub

hub has default arguments for many commands that fill in either your current repo or your own username if one is not specified. To make things clearer in the examples, I will use my Github username, TheRealest, whenever hub fills in your own username, and my dotfiles repo when hub fills in your current repo. Whenever you should explicitly state a repo or username I will use the fantastic ionic repo by driftyco. When we're talking about forks I'll use s10wen as my upstream for dotfiles (which is who I originally forked it from).

The hub command

hub is an addon for git which provides a set of commands that make working with Github a lot easier. I won't go over every single one because the examples in the hub help docs (also reachable via man hub) are pretty self explanatory, but just to give you an idea of what hub offers I'll list my most used features.

A little further down this post I'll go over how to alias hub to git. Since you'll basically always be using hub with this alias on your machine, I'm going to use the git command rather than hub in the examples below.

It can be a pain to have to switch between the browser and the terminal to copy Github links over for commands like clone and remote. hub makes this easier by allowing you to use the familiar username/repo syntax to refer to a repo on Github. Cloning a repo becomes as easy as:

> git clone TheRealest/dotfiles

This works for any command that expects a link to a repo. If you omit the slash and only use one argument hub will assume it is either a username (with your current repo name) or a repo name (with your username) depending on the command:

> cd ~/projects/dotfiles
> git remote add upstream s10wen
git remote add s10wen git://github.com/s10wen/dotfiles.git

> cd ~/new_projects
> git clone dotfiles
git clone git://github.com/TheRealest/dotfiles.git

New commands

There are a few new commands hub provides to allow you to perform actions from the command line that are normally restricted to the website. If you can get used to these commands, you only really need to use github.com to view existing issues and pull requests (if you've found a good way to review, comment on, merge, or close issues and pull requests from the command line, please let me know!).

The first of these is create, a variation on the standard init. While init sets up a directory as a git repo, create also goes out and creates a repo with the same name on Github, setting up an origin remote for you.

If you want to fork a repo with the intention of working on it on your local machine, the easiest way to do so is to clone the original repo with git clone username/repo and then do git fork from inside your newly cloned project. This will do the same thing as clicking the fork button on Github, though you may need to mess with the remotes a bit. After a clone and fork from the command line you will have an origin remote pointing to the original repo, and a remote named after your username pointing to your fork. I usually rename these so that they use the more typical upstream/origin naming convention.

pull-request just creates a pull request for you on Github. By default it uses master as the base for the pull request, and if your repo is a fork it uses the upstream master branch. You can specify a branch as the base of your pull request with -b (still at the upstream repo by default if you're working on a fork).

Finally, browse is a quick way to open pages on github.com in your browser. Without any arguments it opens your repo page (or the page of the upstream repo if you're working on a fork), but there options for going straight to a specific issue or pull request, commit, or even another repo entirely. The -u command will output the URL instead of opening the page, and if you're better with bash than I am you could probably pipe this into hub's beefed up merge command which can take a link to a pull request or commit.

Sprucing up old favorites

As I mentioned above, hub will let you specify a github.com link for merge, cherry-pick, and checkout. You could use this to work with pull requests, but I find it so easy to merge a pull request and delete the feature branch on Github that I haven't really used this feature.

Last but certainly not least, you can push a branch to multiple remotes at the same time like this:

> git push origin,deploy master
git push origin master
git push deploy master

You can do the same with fetch, and if you specify a remote name that doesn't exist, hub will try to create a new remote before fetching. The way hub creates the remote is best shown through example:

> git fetch s10wen,origin
git remote add s10wen git://github.com/s10wen/dotfiles.git
git fetch s10wen
git fetch origin

Installing hub

Installing hub is as simple as:

> brew install hub

To check that everything is installed correctly try the following:

> hub version
git version 2.3.5
hub version 2.2.0

You should get version numbers for both git and hub.

After you install hub you will want to alias the hub command to git so you don't have to remember when to use one or the other. Fortunately hub provides a convenience method that determines the appropriate aliasing syntax based on your system, so you only need to add one line to your .bash_profile or another file your shell sources on login:

> eval "$(hub alias -s)"

Now any time you use the git command in your terminal, hub will deal with what it can and then delegate the rest to git. Now your git has superpowers!

My git aliases

I'm a big fan of using aliases with git, and hub is no exception. Here's an excerpt from my ~/.gitconfig file with a list of my aliases for hub commands:

[alias]
  pr = pull-request
  pro = pull-request -o
  prmks = pull-request -b TheRealest -o
  cl = clone
  bw = browse
  bwi = "! f() { hub browse -- issues/$1; }; f"

The difference between pr and pro is that pro will open the page of the pull request on Github after it is created. I use prmks for submitting pull requests at MakerSquare where we always base our pull requests on a branch named after our username, to keep all of the students' work organized.

The bw command opens the project page on Github, while bwi takes a number and opens the page of the pull request or issue with that number. The bash function is necessary because git automatically inserts a space between aliases and further arguments, but the hub command requires that issues/## not have a space when used with the browse command.