Improve Your Git Workflow With Github Hub
Janne Kemppainen |GitHub is an essential part of development for many software projects and it has a pretty good user experience on the website. However, sometimes you just want to do things from the command line. This is where the hub
utility program comes in handy.
GitHub Hub is a small helper tool that lets you manage many of the GitHub features, such as opening pull requests, creating repositories, etc., straight from the command line. In this post I will show you most of the key features, and I’ve added some command aliases that should make your experience with hub
even better.
For this post I assume that you have set up SSH keys for GitHub.
Installation
Mac OS
The easiest way is to install with Homebrew.
>> brew install hub
Linux
You can try installing the hub
package from the package manager of your distro, or use the same method as with the Windows Subsystem for Linux Ubuntu.
Windows Subsystem for Linux
At first it seemed that the best way for WSL would to be to install from source as the hub
package wasn’t available from apt
. However, I had some problems with the Go paths and the installation script didn’t seem to find any of the Go libraries so I decided to choose an alternative route.
Homebrew has a Linux counterpart called Linuxbrew which also works for WSL and the hub
package is available there so this seems to be the easiest way for WSL. First make sure that you’ve got all the dependencies for Linuxbrew installed:
>> sudo apt-get install build-essential curl file git
Then install Linuxbrew with the command from the Homebrew on Linux page:
>> sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"
Finalize the installation by adding brew
to PATH
and to the shell profile:
>> test -d ~/.linuxbrew && eval $(~/.linuxbrew/bin/brew shellenv)
>> test -d /home/linuxbrew/.linuxbrew && eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)
>> test -r ~/.bash_profile && echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.bash_profile
>> echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.profile
Now you can install hub
:
>> brew install hub
Hub lets you open web pages directly from the command line so you need to set the $BROWSER environment variable for it to know what browser to use. Edit your .bashrc
file
>> nano ~/.bashrc
and add the following line:
export BROWSER='/mnt/c/Windows/explorer.exe'
This sets the explorer.exe
as the default browser which will then direct to your Windows system default browser such as Chrome or Firefox.
Cloning repositories
You can clone existing repositores by their names. You don’t need to include the username when cloning your own repositories:
>> hub clone myproject
Cloning into 'myproject'...
remote: Enumerating objects: 18, done.
remote: Counting objects: 100% (18/18), done.
remote: Compressing objects: 100% (16/16), done.
remote: Total 18 (delta 1), reused 17 (delta 0), pack-reused 0
Receiving objects: 100% (18/18), done.
Resolving deltas: 100% (1/1), done.
but you need to give the full name when using a repository from an organization or another user:
>> hub clone pakstech/twitter-followers
Cloning into 'twitter-followers'...
remote: Enumerating objects: 32, done.
remote: Counting objects: 100% (32/32), done.
remote: Compressing objects: 100% (22/22), done.
remote: Total 32 (delta 9), reused 29 (delta 6), pack-reused 0
Receiving objects: 100% (32/32), 170.84 KiB | 813.00 KiB/s, done.
Opening in a browser
If you are inside a Git repository you can open the GitHub page of your project:
>> hub browse
This uses the $BROWSER environment variable to choose which browser should be used.
Instead of opening the browser you can also print the URL with the -u
or --url
flag or copy to the clipboard with -c
or --copy
. For copying you’ll need to install xclip
(sudo apt install xclip
, etc.).
The hub browse
command takes two (optional) positional parameters: the repository and the subpage. If I want to go to the pull requests page of my twitter-followers
project I can get there with this command:
>> hub browse pakstech/twitter-followers pulls
And bam! I’m immediately there sorting through the PR’s.
But it isn’t that fun to define the name of the repository every time, right? That’s why you can use double hyphens (--
) as a placeholder for the repository before the subpage. Therefore if you are inside a Git repository you can go to its pull requests page with the shortened command:
>> hub browse -- pulls
To make it even easier let’s create an alias for this. Edit the ~/.bashrc
file and append the following line at the end
alias pulls='hub browse -- pulls'
After saving the file, restart the terminal or reload the configurations with source ~/.bashrc
. Now if you are inside a GitHub project directory this is all you need to do to open the pull requests page:
>> pulls
Implementing a new feature
Let’s say that you have a user story that you want to implement to your project. The first thing you need to do is to create the feature branch normally.
>> git checkout -b my_feature
We could for example want to improve the documentation in the README.md file. So after making the necessary edits you would then add, commit and push normally.
>> git add README.md
>> git commit -m "Improve documentation"
>> git push -u origin my_feature
Now you’d normally have to go to the project page on GitHub and create a new pull request from there. With Hub you can do it from the terminal:
>> hub pull-request
This opens a new text editor where you can type the title of the PR on the first line. Leave a blank line after the title and write the PR description in Markdown after that.
There is also the pr
command which allows you to list or checkout pull requests. Checking out a pull request locally is quite easy:
>> hub pr list
#5 Add new feature enhancement
#4 Fix nasty bug bug
>> hub pr checkout 4
Switched to branch 'bug_fix'
Your branch is up to date with 'origin/bug_fix'.
Already up to date.
Opening an existing pull request in a browser
Unfortunately it is not possible to edit an existing pull request from the command line as of now. That feature would be really helpful as you could add reviewers and labels, or change the description later, for example. It seems that you can’t open the PR page of the current branch either if it already exists (during PR creation you can use the -o
flag to open in a web browser, though).
Well, at least we can do same magic of our own with the standard Unix tools to open an existing pull request:
>> hub pr list -f '%I %H%n' | grep `git rev-parse --abbrev-ref HEAD` | awk '{split($0, a); printf "pull/%s", a[1]}' | xargs hub browse --
Let me split that into pieces so that you can understand what’s going on here. The first part uses the hub pr list
command which lists all pull requests for the repository. The -f
argument defines the output format, in this case the pull request number and the head branch separated with a single space and ending with a newline character.
The output of the previous command is piped to grep which finds the name of the current branch with git rev-parse
and returns the matching line if it exists in the PR list. Then the awk command splits the result by whitespace and selects the first element (the PR number) and prints in the format ‘pull/{number}’.
Finally the result, for example pull/1
, is given as the last parameter to the hub browse
command with xargs. The final result of the command will therefore be something like hub browse -- pull/1
. Add this as an alias to your ~./bashrc
file:
alias pull=OpenPullRequestPage
function OpenPullRequestPage()
{
hub pr list -f '%I %H%n' | grep `git rev-parse --abbrev-ref HEAD` | awk '{split($0, a); printf "pull/%s", a[1]}' | xargs hub browse --
}
After sourcing the bash configurations you can now use pull
to open the PR of the current branch! If you haven’t created a PR yet or if you are on the master branch then it will just open the project page which is a graceful fallback.
GitHub releases
GitHub releases are Git tags that contain additional information such as release notes and perhaps other assets such as compiled executables. You can create a new release with:
>> hub release create v1.0
A text editor window will open. Add the title and description as you would for a pull request. After saving Hub will create the release on GitHub with the tag that was specified, in this case v1.0.
When you have releases in your GitHub repository you can list them all simply with
>> hub release
If there are lots and lots of releases in your repository you can limit the returned amount with the -L
option.
You can also check the release notes for a specific tag:
>> hub release show v1.0
This is the initial release
This release has many useful things, and it can be edited
Editing an existing release is also possible with the hub release edit
command. Just give the Git tag as a parameter and the text editor will open letting you change the release description.
I also came up with some Bash aliases for working with release drafts. You can add them to your Bash configurations if you find them useful.
alias list-drafts="hub release --include-drafts -f '%S %T %t%n' | grep -e '^draft'"
alias draft-release='hub release create --draft'
alias publish-release='hub release edit -m "" --draft=false'
This adds three new commands for managing releases. The first one is for listing all releases that are still drafts. Type draft-list
and their tags and names will be listed.
>> list-drafts
draft v1.3 This is some feature
To create a new draft use the draft-release
alias and give the desired version tag as a parameter.
>> draft-release v1.3
Edit the release notes and save. The release will be shown as a draft on the GitHub page. Finally, you can publish the draft as a release:
>> publish-release v1.3
The empty string parameter -m ""
in the alias instructs hub release edit
to use the existing message so the text editor won’t open.
Comparing changes
When you are on a feature branch you can compare the changes against the master branch without defining any parameters:
>> hub compare
The comparison page will open on a new browser tab.
To compare the changes between releases give the desired tags separated by two or three dots:
>> hub compare v1.0..v1.1
In addition to tags, branch names and commit SHAs are also valid range parameters. The end range defaults to the current branch name if it is omitted.
Working with GitHub Enterprise
You might be working in a company where the code is hosted on a separate GitHub Enterprise installation. Hub works with GHE too but requires configurations first. You need to add your GitHub Enterprise host to the hub whitelist in git configurations, for example:
>> git config --global --add hub.host github.example.com
Now the hub commands work the same way for GHE repositories. The init
and clone
commands need to know which GitHub to use so you can specify the GITHUB_HOST
environment variable.
>> GITHUB_HOST=git.example.com hub clone username/repository
The documentation says that Hub defaults to github.com but for me it asks which one to use if I don’t specify the selection with the environment variable.
Conclusion
Hopefully this was helpful to you and you learned something new. You can read more about the available commands from the hub manual.
Discuss on Twitter
You can open an existing PR on @github with this simple hub command:
— Janne Kemppainen (@pakstech) April 23, 2019
hub pr list -f '%I %H%n' | grep `git rev-parse --abbrev-ref HEAD` | awk '{split($0, a); printf "pull/%s", a[1]}' | xargs hub browse --#hub #wsl #githttps://t.co/CQFMYHUhrG
Previous post
Getting Started With Mosquitto on a Raspberry PiNext post
Hugo Single Page Templates