Many people are becoming involved with open source software development by contributing to projects on GitHub. Many of them use GitHub's graphical user interface (GUI), especially those who are new to the command-line interface (CLI). But what if you prefer working on the command line?
I recently came across hub, a command-line tool that extends Git by adding GitHub-specific features to make it easier to become familiar with Git commands. So, if you're tired of point-and-click GUIs but want some help with Git's sometimes confusing syntax, hub is the tool for you.
Before reading further, it's a good idea to review Git terminology first.
The use of hub depends on Git, so first, confirm we have it installed:
Your Git version must be 1.7.3 or newer. Don't worry if it's missing; you can quickly install it using Homebrew, an open source package manager, or the built-in package manager for your distribution (dnf, apt, etc). I like Homebrew, so we will stick with that. Homebrew was previously known as Linuxbrew on Linux, but it now uses the same name as the macOS version. It can be installed in your home directory, which means you don't need sudo permission to install applications with it. If you prefer another installation method, see the Git documentation.
To install brew, Homebrew's command-line utility, on Fedora:
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
Since we didn't use sudo, the installation script installs Homebrew to ~/.linuxbrew. To learn more about how it works, see the documentation.
Next, let's install hub using brew.
$ brew install hub
Next, verify hub is installed correctly by checking its version:
$ hub --version git version 2.25.0 hub version 2.14.1
The output shows the versions of both hub and Git. Voila! You have successfully installed hub.
Getting started with hub
Give hub a spin using a new repository you will host on GitHub. Navigate to any folder where you want to initialize Git:
$ cd Documents $ mkdir Test; cd Test/ $ git init Initialized empty Git repository in /Users/SudeshnaSur/Test/.git/
Place any file inside it. Git only sees files that have changed, so add some text to it using echo:
$ echo "Hello" > test.txt
Check the git status and add:
$ git status On branch master No commits yet Untracked files: test.txt nothing added to commit but untracked files present $ git add .
By using git add, we have staged the changes but not yet committed them. We need an account before we do that. If you don't already have one, create a GitHub account using this step-by-step guide. Next, we need to configure our local version of Git to use the account's username and email. This information will be in every commit message you add to any repository (since you are setting it to be global):
git config --global user.email "email@example.com" git config --global user.name "Your Name"
It is worth noting you can make your email to be private using this feature. Either way, set your email to your GitHub email address.
Now, we can create a commit that will be assigned to our username. Let's check in the existing change:
$ git commit -m 'Adding a test file' [master (root-commit) 07035c94e038] Adding a test file 1 file changed, 1 insertion(+) create mode 100644 test.txt $ git status On branch master nothing to commit, working tree clean
Using the fancy features of hub
Up to now, everything has been the same as using git. Here is where it gets interesting.
Now if you type hub create, it will create a new repository on GitHub with the same name as the current directory:
$ hub create Updating origin https://github.com/SudeshnaSur/Test
Using hub even links your repository with the remote mirror:
$ git remote -v origin firstname.lastname@example.org:SudeshnaSur/Test.git (fetch) origin email@example.com:SudeshnaSur/Test.git (push)
Cloning and forking with hub
You can also clone and fork using hub instead of clicking-through to the GitHub GUI. I enjoy that hub automatically recognizes the repository we are targeting as long as it has a namespace, then a slash, then the repository name. So if we want to clone the source code for hub itself, available at https://github.com/github/hub, we only need to write:
$ hub clone github/hub Cloning into 'hub'... remote: Enumerating objects: 26, done. remote: Counting objects: 100% (26/26), done. remote: Compressing objects: 100% (22/22), done. remote: Total 19712 (delta 7), reused 13 (delta 4), pack-reused 19686 Receiving objects: 100% (19712/19712), 6.76 MiB | 7.25 MiB/s, done. Resolving deltas: 100% (12912/12912), done.
Now I can do a normal change to my copy of the repository. I will create a branch called topic, check out the branch, then make a minor change and commit it (these are all standard Git commands):
$ cd hub $ git checkout -b topic Switched to a new branch 'topic' $ echo “Hey” >test2.txt $ git add . $ git commit -m ‘Adding test 2’ [master cbb6fde5805a] Adding test 2 1 file changed, 1 insertion(+) create mode 100644 test2.txt
This clone is currently github/hub, which I do not have write access to. But I can easily fork the repository and push changes to it:
$ hub fork –remote-name origin
The output reports that your account is forking the original repositories and all its branches. Note that if you have already have a remote named origin, hub will default to giving the new remote the same name as your username (if this terminology is confusing, read this refresher on remotes and forks). Next, let's push the branch, topic, to my fork:
$ git push origin topic
I can now open a pull request (PR) directly from the command line by typing:
$ hub pull-request
This will open a text editor so I can add a PR message, and I can then manage the PR from there. I can even manage other PRs from the command line with the hub pr list command.
Using other hub features
The story doesn't end here; hub provides many other features:
- Check the continuous integration (CI) status for our branches:
$ hub ci-status
- Open a project in your default web browser:
$ hub browse github/quickstart
- Synchronize all your local branches to match the remote's latest state:
$ hub sync
- List issues assigned to your name:
$ hub issue --assignee User_Name
- List open issues in the repository you are in:
$ hub issue --limit 20 [lists only 20 issues]
- Open the current project's issues page:
$ hub browse --issues
- Check out a PR while reviewing a PR:
$ hub pr checkout 123
- Close an issue after merging:
$ hub issue update 123 --state closed
- Transfer issue to a new repository:
$ hub issue transfer 123 ANOTHER-REPO
- Delete a repository in GitHub:
$ hub-delete github/wiki-links
Hub is both helpful and easy to use from the command line. If you're transitioning from the GUI to the command line and want to make that experience more intuitive, give hub a try.