Video

Want to see the full-length video right now for free?

Notes

Gitsh is an open-source project by thoughtbot. A few of our developers noticed that they were typing git an awful lot, since git commands come in groups (git status, git add ., git commit -m "Ship it!", git push). Even if you've aliased to just "g", it's still repetitive.

They wished for a context specific to git from which to perform git operations; so they built the gitsh program, an interactive shell for git. From within gitsh you can issue any git command directly, without needing to precede it with git, and even still use your local aliases and configuration.

This might seem like a relatively minor optimization, but I've found that the small productivity boosts that gitsh gives you add up to more than the sum of their parts. Now that I've lived with gitsh for a few weeks, I won't be going back.

Usage

Installation is straightforward. You can then run the gitsh command:

$ gitsh
gitsh 0.10
Type :exit to exit
conflict-demo master@

You are now at a gitsh prompt, which tells you the working directory, branch, and current status (the @ symbol); we get all this without having to configure our (standard) shell, as we would normally have to do. If you want to return to your standard shell, press ctrl-d.

If you make some changes, your prompt will change colors and have a different symbol (&) at the end to indicate that you have uncommitted changes.

Easy git status

Which brings us to gitsh's first Big Win: since we are in a context specific to git, there's no reason to have an empty command do nothing; so instead, simply pressing return runs the most common git command of all -- git status.

Easy everything else

And now for gitsh's second Big Win: To run any other git command, you now can just say its name without preceding it with git:

conflict-demo master& add .
conflict-demo master& commit -m "Ship it!"
conflict-demo master@ push

Everything works as expected; gitsh will open an editor when required, etc.

Aliases & Custom Subcommands

Additionally, any aliases and custom commands that you have already configured are available to gitsh. For example,

conflict-demo master& help df
`git df' is aliased to `diff --word-diff --color-words'
conflict-demo master& help aa
`git aa' is aliased to `add --all'

So we can now very cleanly perform a whole git "sequence":

conflict-demo master&     # just press return for status
conflict-demo master& df  # displays diff
conflict-demo master& aa  # add all
conflict-demo master& cm  # commit
conflict-demo master@     # prompt changes to indicate commit succeeded

Shell Commands

If you need to run standard shell commands, gitsh has an escape hatch: just precede the command with a !:

conflict-demo feature@ !ls -FG
README.md app/ config.rb script.rb

Internal Commands

There are also internal commands specific to gitsh, which are preceded by a :. For example, you can navigate through the repo's directories with :cd:

conflict-demo feature@ :cd app/
app feature@ !ls
sample.rb

You can make temporary changes to your git configuration with the :set command. So, for example, while pair programming, you can easily set the committer's name and email:

conflict-demo feature@ :set user.name 'Chris Toomey'
conflict-demo feature@ :set user.email chris@thoughtbot.com
conflict-demo feature@ cm -m 'We are pair programming'

These changes will be forgotten at the end of that gitsh session.

Configuration

Like any good Unix tool, gitsh is configurable.

gitsh Section of gitconfig

You can add a section to your ~/.gitconfig file specific to gitsh:

[gitsh]
  noGreeting = true
  defaultCommand = status --short --branch && :echo
[gitsh "color"]
  default = cyan
  untracked = yellow
  modified = red

The noGreeting option turns off the welcome message when you first launch gitsh. The defaultCommand option allows you to choose precisely what happens when you just press return at a gitsh prompt.

gitshrc

There is also a dotfile for gitsh, ~/.gitshrc, which allows you to create your own welcome message (among other things):

log --oneline --decorate -1
:echo
status --short --branch

The Next Level

There are two additional configurations that really made gitsh an indispensable part of my workflow:

Tmux binding

The following binding will give you a handy "git drawer" that you can quickly jump in and out of:

bind-key g split-window -h -p 50 gitsh

Running <prefix>g in tmux will open a new pane to the right of the current pane, using 50% of the available space. You can then interact with gitsh as needed, and then exit gitsh with <C-d>. Since the pane was started with the gitsh command, the pane will also be closed when gitsh exits. How handy!

Vimdiff

The one major piece I missed from my previous Vim + fugitive.vim setup was the side by side diffs in Vim. Luckily, we can use Vim for viewing diffs on an as needed basis by enabling it as git's difftool.

$ git config --global diff.tool vimdiff
$ git config --global alias.vdf difftool

Now, whenever you need the extra clarity of Vim's side by side diff, we can run vdf and gitsh/git will open Vim in diff mode.

Conclusion

Again, I want to highlight that while this might seem like just a collection of nice shortcuts for Git interaction, in my experience they add up to a whole lot more. If you're a heavy Git user, you owe it to yourself to try out gitsh and see if it's right for you!