Making your life easier with «Hub» from GitHub

April 07, 2019

I find that the most annoying part of working with GitHub is the necessity to switch back and forth between terminal and web interface to either copy a repo name, to see pull requests/issues or to fork stuff. Wouldn’t it be much easier if I could just write something like git repos and get the list, so that I can just clone it right away.

Enter «Hub»

If you’ve been working with github for some time you probably know or use the hub project from GitHub. Well, recently they added something that might change the way you work with GitHub: hub api command that allows you to use any of GitHub API and make graphql queries.

Let’s make some aliases

You can find a bit more information on git aliases in my previous post.

Generally, after you’ve installed hub you will alias it to git, so that it wraps all basic functions while adding its own(run hub alias for settings in your shell). Now, let’s take a look at problems above.

Git repos

First we want to get list of user’s github repositories. I found an elegant solution to list a random user repos in one of hubs issues. All we need is to add a function that will tell us a logged in user. To do that we need to add following alias into ~/.gitconfig:

[alias]
  user = "!f() { hub api --flat user | grep .login | awk '/.login/ {print $2}'; }; f"

now we need to break down the script we found into several aliases:

[alias]
  # this function allows you to go through hub low level api with or without multiple pages
  paginate = "!paginate() { local output cursor; output=\"$(\"$@\")\"; cursor=\"$(awk '/\\.hasNextPage/ { has_next=$2 } /\\.endCursor/ { if (has_next==\"true\") print $2 }' <<<\"$output\")\"; printf \"%s\\n\" \"$output\"; [ -z \"$cursor\" ] || paginate \"$@\" -f after=\"$cursor\"; }; paginate "

  repos = "!repos() { local user=\"${1?}\";shift 1; git paginate hub api -t graphql -f user=\"$user\" \"$@\" \
  -f query='query($user: String!, $per_page: Int = 100, $after: String) { user(login: $user) { \
  repositories(first: $per_page, after: $after) { nodes { nameWithOwner }, pageInfo { hasNextPage, endCursor } } } }';}; \
  repos \"$(git user)\" | awk '/\\.nameWithOwner\\t/ { print $2 }';"

as a result you can just type git repos and it will list all your GitHub repos:

gko/dotfiles
gko/vimio
gko/concat
...

Git comment

Hub allows you to view, create or close any repo’s issue from terminal using hub issue command. But there is no default way to post a comment from the terminal. But using hub api we can do just that:

[alias]
  comment = "!f() { hub api \"repos/{owner}/{repo}/issues/$1/comments\" --raw-field \"body=$2\"; }; f"

now we can just type git comment <ISSUE NUMBER> "Some comment" and it will be posted for us.

Hub browse

Another amazing hub feature is hub browse that allows you to view a project main page, or any subpage(i.e. «/issues») as following:

[alias]
  issues = browse -- issues
  wiki = browse -- wiki

More stuff

You can see the examples above and some other cool stuff in the gitconfig file from my dotfiles repo.