hub is a command line tool that wraps git
in order to extend it with extra
features and commands that make working with GitHub easier.
$ hub clone rtomayko/tilt
# expands to:
$ git clone git://github.com/rtomayko/tilt.git
hub is best aliased as git
, so you can type $ git <command>
in the shell and
get all the usual hub
features. See "Aliasing" below.
Dependencies:
- git 1.7.3 or newer
- Ruby 1.8.6 or newer
Installing on OS X is easiest with Homebrew:
$ brew install hub
hub
is easily installed as a standalone script:
$ curl http://defunkt.io/hub/standalone -sLo ~/bin/hub &&
chmod +x ~/bin/hub
Assuming "~/bin/" is in your $PATH
, you're ready to roll:
$ hub version
git version 1.7.6
hub version 1.8.3
Though not recommended, hub can also be installed as a RubyGem:
$ gem install hub
(It's not recommended for casual use because of the RubyGems startup time. See this gist for information.)
$ gem install hub
$ hub hub standalone > ~/bin/hub && chmod +x ~/bin/hub
This installs a standalone version which doesn't require RubyGems to run, so it's faster.
You can also install from source:
$ git clone git://github.com/defunkt/hub.git
$ cd hub && rake install prefix=/usr/local
Is your prompt slow? It may be hub.
-
Check that it's not installed using RubyGems.
-
Check that RUBYOPT isn't loading anything shady:
$ echo $RUBYOPT
-
Check that your system Ruby is speedy:
$ time /usr/bin/env ruby -e0
If #3 is slow, it may be your GC settings.
Using hub feels best when it's aliased as git
. This is not dangerous; your
normal git commands will all work. hub merely adds some sugar.
hub alias
displays instructions for the current shell. With the -s
flag, it
outputs a script suitable for eval
.
You should place this command in your .bash_profile
or other startup script:
eval "$(hub alias -s)"
hub repository contains tab-completion scripts for bash and zsh. These scripts complement existing completion scripts that ship with git.
Assuming you've aliased hub as git
, the following commands now have
superpowers:
$ git clone schacon/ticgit
> git clone git://github.com/schacon/ticgit.git
$ git clone -p schacon/ticgit
> git clone git@github.com:schacon/ticgit.git
$ git clone resque
> git clone git@github.com/YOUR_USER/resque.git
$ git remote add rtomayko
> git remote add rtomayko git://github.com/rtomayko/CURRENT_REPO.git
$ git remote add -p rtomayko
> git remote add rtomayko git@github.com:rtomayko/CURRENT_REPO.git
$ git remote add origin
> git remote add origin git://github.com/YOUR_USER/CURRENT_REPO.git
$ git fetch mislav
> git remote add mislav git://github.com/mislav/REPO.git
> git fetch mislav
$ git fetch mislav,xoebus
> git remote add mislav ...
> git remote add xoebus ...
> git fetch --multiple mislav xoebus
$ git cherry-pick http://github.com/mislav/REPO/commit/SHA
> git remote add -f mislav git://github.com/mislav/REPO.git
> git cherry-pick SHA
$ git cherry-pick mislav@SHA
> git remote add -f mislav git://github.com/mislav/CURRENT_REPO.git
> git cherry-pick SHA
$ git cherry-pick mislav@SHA
> git fetch mislav
> git cherry-pick SHA
$ git am https://github.com/defunkt/hub/pull/55
> curl https://github.com/defunkt/hub/pull/55.patch -o /tmp/55.patch
> git am /tmp/55.patch
$ git am --ignore-whitespace https://github.com/davidbalbert/hub/commit/fdb9921
> curl https://github.com/davidbalbert/hub/commit/fdb9921.patch -o /tmp/fdb9921.patch
> git am --ignore-whitespace /tmp/fdb9921.patch
$ git apply https://gist.github.com/8da7fb575debd88c54cf
> curl https://gist.github.com/8da7fb575debd88c54cf.txt -o /tmp/gist-8da7fb575debd88c54cf.txt
> git apply /tmp/gist-8da7fb575debd88c54cf.txt
$ git fork
[ repo forked on GitHub ]
> git remote add -f YOUR_USER git@github.com:YOUR_USER/CURRENT_REPO.git
# while on a topic branch called "feature":
$ git pull-request
[ opens text editor to edit title & body for the request ]
[ opened pull request on GitHub for "YOUR_USER:feature" ]
# explicit title, pull base & head:
$ git pull-request "I've implemented feature X" -b defunkt:master -h mislav:feature
$ git pull-request -i 123
[ attached pull request to issue #123 ]
$ git checkout https://github.com/defunkt/hub/pull/73
> git remote add -f -t feature git://github:com/mislav/hub.git
> git checkout --track -B mislav-feature mislav/feature
$ git checkout https://github.com/defunkt/hub/pull/73 custom-branch-name
$ git merge https://github.com/defunkt/hub/pull/73
> git fetch git://github.com/mislav/hub.git +refs/heads/feature:refs/remotes/mislav/feature
> git merge mislav/feature --no-ff -m 'Merge pull request #73 from mislav/feature...'
$ git create
[ repo created on GitHub ]
> git remote add origin git@github.com:YOUR_USER/CURRENT_REPO.git
# with description:
$ git create -d 'It shall be mine, all mine!'
$ git create recipes
[ repo created on GitHub ]
> git remote add origin git@github.com:YOUR_USER/recipes.git
$ git create sinatra/recipes
[ repo created in GitHub organization ]
> git remote add origin git@github.com:sinatra/recipes.git
$ git init -g
> git init
> git remote add origin git@github.com:YOUR_USER/REPO.git
$ git push origin,staging,qa bert_timeout
> git push origin bert_timeout
> git push staging bert_timeout
> git push qa bert_timeout
$ git browse
> open https://github.com/YOUR_USER/CURRENT_REPO
$ git browse -- commit/SHA
> open https://github.com/YOUR_USER/CURRENT_REPO/commit/SHA
$ git browse -- issues
> open https://github.com/YOUR_USER/CURRENT_REPO/issues
$ git browse schacon/ticgit
> open https://github.com/schacon/ticgit
$ git browse schacon/ticgit commit/SHA
> open https://github.com/schacon/ticgit/commit/SHA
$ git browse resque
> open https://github.com/YOUR_USER/resque
$ git browse resque network
> open https://github.com/YOUR_USER/resque/network
$ git compare refactor
> open https://github.com/CURRENT_REPO/compare/refactor
$ git compare 1.0..1.1
> open https://github.com/CURRENT_REPO/compare/1.0...1.1
$ git compare -u fix
> (https://github.com/CURRENT_REPO/compare/fix)
$ git compare other-user patch
> open https://github.com/other-user/REPO/compare/patch
$ hub submodule add wycats/bundler vendor/bundler
> git submodule add git://github.com/wycats/bundler.git vendor/bundler
$ hub submodule add -p wycats/bundler vendor/bundler
> git submodule add git@github.com:wycats/bundler.git vendor/bundler
$ hub submodule add -b ryppl ryppl/pip vendor/pip
> git submodule add -b ryppl git://github.com/ryppl/pip.git vendor/pip
$ git help
> (improved git help)
$ git help hub
> (hub man page)
Hub will prompt for GitHub username & password the first time it needs to access the API and exchange it for an OAuth token, which it saves in "~/.config/hub".
If you prefer using the HTTPS protocol for GitHub repositories instead of the git protocol for read and ssh for write, you can set "hub.protocol" to "https".
# default behavior
$ git clone defunkt/repl
< git clone >
# opt into HTTPS:
$ git config --global hub.protocol https
$ git clone defunkt/repl
< https clone >
These instructions assume that you already have hub installed and aliased as
git
(see "Aliasing").
- Clone hub:
git clone defunkt/hub && cd hub
- Install development dependencies:
bundle install
- Verify that existing tests pass:
bundle exec rake
- Create a topic branch:
git checkout -b feature
- Make your changes. (It helps a lot if you write tests first.)
- Verify that tests still pass:
bundle exec rake
- Fork hub on GitHub (adds a remote named "YOUR_USER"):
git fork
- Push to your fork:
git push -u YOUR_USER feature
- Open a pull request describing your changes:
git pull-request
- Home: https://github.com/defunkt/hub
- Bugs: https://github.com/defunkt/hub/issues
- Gem: https://rubygems.org/gems/hub
- Authors: https://github.com/defunkt/hub/contributors
These projects also aim to either improve git or make interacting with GitHub simpler: