Github From Your Terminal

October 2, 2018
productivity hacks

A while back I shared some of my favorite Git tricks. Aside from useful short aliases, prettier logs, and fancy pull commands, I mentioned Hub. Hub is a tools that wraps Git, and adds a bunch of extra goodies for working with Github. In this blog I want to focus on how I work with Github, and especially Github issues, from the command line.

Git and Github - a refresher

If you don’t already have Hub installed, here’s the short version of what you need to do.

First, we need to install Hub. Use whatever package manager you like. Don’t know where to start? If you’re on a Mac, check out Homebrew. For Windows, have a look at Chocolatey. On Linux, you probably know what to do. I’m on a Mac, so:

$ brew install hub

Then, to really wrap the git command, we need to configure our shell. Most people will be using Bash, so I’ll focus on that. If you’re using anything else, you’re probably familiar with configuring your shell anyway.

if which hub &> /dev/null ; then
  alias git=hub
fi

To check if everything works:

$ git version
git version 2.19.0
hub version 2.5.1

For more info on what Hub can do for you and how to set it up, see the Hub webpage.

Working with Github

So, now that we have Hub installed, and have our git command aliased to it, we can suddenly do some extra things. For instance, we can create a new repository. Let’s create a private Github repo for our new award-winning idea:

$ git init foobar
$ cd foobar
$ git create -p -d "Award-winning idea"
Updating origin
https://github.com/bennycornelissen/foobar

The -p flag marks the repo as private. If you’re a non-paying Github user, this will probably not work for you. new repo

You can also remove Github repos, but only if you created the OAuth token with delete_repo permissions. If you don’t have this set, you’ll get something like this:

$ git delete -y foobar
Please edit the token used for hub at https://github.com/settings/tokens
and verify that the `delete_repo` scope is enabled.
Error deleting repository: Forbidden (HTTP 403)
Must have admin rights to Repository.

Working with Issues and Pull Requests

If you’re contributing to Open Source projects, or if you happen to track your backlog in Github itself (instead of tools like Trello or JIRA), you may appreciate some of the functionality that Hub offers with regard to Github Issues and Pull Requests. I personally hate switching back and forth between my terminal and a browser window to do things like creating pull requests or checking issues. I also created some aliases for these Hub commands, to either make them more convenient, set some defaults, or format the output in a way that I like. Let’s take a look at some examples:

Checking Pull Requests for an Open Source project

I use HashiCorp’s Terraform quite a bit, so I have that repo checked out locally. To see what the 10 newest PRs are, we can run:

$ git pr list -L 10

terraform new PRs

Unfortunately, this only gives me a listing, but not much else. I would love to be able to quickly open a PR in my browser, see when it was updated, or how many comments a PR has. But nobody wants to venture into the rabbit-hole that is git pretty-format multiple times a day. So I’ve added an alias for that in my .gitconfig:

  # Get list of PRs
  prs = !hub pr list -f '%sC%>(8)%i%Creset | %>(15)%ur | %NC | %sC%<(56)%U%Creset | %t  %l %n'

So, let’s check again what the 10 newest PRs are:

$ git prs -L 10

terraform new PRs with formatting

Much better. If I quickly want to look at the PR, I can click the relevant URL. To check out the code for the most recent PR, I can quickly run:

$ git pr checkout 18973
remote: Enumerating objects: 13, done.
remote: Counting objects: 100% (13/13), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 13 (delta 7), reused 13 (delta 7), pack-reused 0
Unpacking objects: 100% (13/13), done.
From github.com:hashicorp/terraform
 * [new ref]             refs/pull/18973/head -> oct18_plugins
Switched to branch 'oct18_plugins'

Creating Pull Requests

If you want to create your own PR, you can use the pull-request subcommand. I usually want my PR to merge to master, and if I’m done, I want to clean up my feature branches. So I created the following aliases:

  # create PR to master quickly
  prnew = !sh -c 'hub pull-request -b master'

  # clean up after PR has been merged
  prdone = !sh -c 'git co ${1-master} && git up && git clean-merged'

This means I can quickly create a PR from my feature branch by running git prnew, and after it has been merged, I can clean up with git prdone. Neat.

If you want to check the CI status for a branch without opening your browser, Hub is your friend once more:

$ git ci-status [-v]

ci status

Working with Issues

Issues follow a similar pattern. You can list and create issues from the command line, but the output for listing issues is lacking some useful fields. You can create an issue using the git issue create command, and list issues with the git issue command. But to address some formatting and workflow quirks, I’ve created the following aliases:

  # Get list of GH issues
  issues-all = !hub issue -s all -o updated -f '%sC%>(8)%i%Creset | %>(15)%ur | %NC | %sC%<(56)%U%Creset | %t  %l %n'
  issues = !hub issue -o updated -f '%sC%>(8)%i%Creset | %>(15)%ur | %NC | %sC%<(56)%U%Creset | %t  %l %n'

The issues-all command only differs from the issues command in that it also lists issues that are closed. This is particularly useful when you want to have a good overview of what happened, or if you work in a team.

To show the 10 most recently updated issues, regardless of their status, we can run:

$ git issues-all -L 10

recent issues

But let’s say we’re particularly interested in the Terraform CLI part, and want to list the 10 most recent open issues that are labeled as bugs. We know labels are used heavily, so we can filter on the ‘bug’ and ‘cli’ labels:

$ git issues -L 10 -l bug,cli

recent cli bugs

Again, I can quickly open a specific issue by clicking the URL.

Things it doesn’t do yet

Hub isn’t quite perfect yet. I’ve found some inconsistencies (like git issue vs git pr list to list things), and some silly omissions. For instance, why can I check the ci-status for a branch, but can’t I show the CI status for every PR when listing them? The Github PR overview does exactly that, and I think it’s useful. But it surely makes working with Github easier when you do most of your work in the terminal.