Want to see the full-length video right now for free?
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.
[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.
[Installation]: https://github.com/thoughtbot/gitsh#installing-gitsh
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
.
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.
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
[aliases and custom commands that you have already configured]: https://upcase.com/videos/git-customizing#custom-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
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.
Like any good Unix tool, gitsh is configurable.
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.
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
There are two additional configurations that really made gitsh an indispensable part of my workflow:
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!
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.
[fugitive.vim]: https://github.com/tpope/vim-fugitive
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!