Git info in your ZSH Prompt

Recently I discovered vcs_info recently. This nicely replaces the horrible hack I was using previously to show current Git status. vcs_info works with VCSes besides Git, and it handles some of the magic and keeps your .zshrc clean, so those are nice benefits.

I used some Unicode to display colored circles. Green if there are staged changes, yellow if there are unstaged changes, and red if there are new untracked-yet-unignored files. Below is a picture.

I like this because I'm constantly forgetting to git add newly-created files. Then I have to add them and amend my commit, and so on. I like a prompt that reminds me that new files showed up that need to be added or ignored.

Code:

autoload -Uz vcs_info

zstyle ':vcs_info:*' stagedstr '%F{28}●'
zstyle ':vcs_info:*' unstagedstr '%F{11}●'
zstyle ':vcs_info:*' check-for-changes true
zstyle ':vcs_info:(sv[nk]|bzr):*' branchformat '%b%F{1}:%F{11}%r'
zstyle ':vcs_info:*' enable git svn
precmd () {
    if [[ -z $(git ls-files --other --exclude-standard 2> /dev/null) ]] {
        zstyle ':vcs_info:*' formats ' [%F{green}%b%c%u%F{blue}]'
    } else {
        zstyle ':vcs_info:*' formats ' [%F{green}%b%c%u%F{red}●%F{blue}]'
    }

    vcs_info
}

setopt prompt_subst
PROMPT='%F{blue}%n@%m %c${vcs_info_msg_0_}%F{blue} %(?/%F{blue}/%F{red})%% %{$reset_color%}'

Picture:

ZSH and Git

Limitations

As you can see in the screenshot, when you have a brand new Git repo (no commits yet), vcs_info fails to show you that there are files staged. It works OK after you have at least one commit though.

vcs_info doesn't (yet?) handle showing untracked files. So I hacked a function to support it.

Finding a good Unicode symbol that displays nicely in monospace font was annoying. If I ever change fonts, I'll likely have to pick a new symbol. It also doesn't display too well in a real tty. Or over SSH when using Putty. So I may have to scrap the stoplights and use plus-signs or something. Sigh.

September 10, 2010 @ 6:31 AM PDT
Cateogory: Linux
Tags: ZSH, Git

18 Comments

Matija "hook" Šuklje
Quoth Matija "hook" Šuklje on September 10, 2010 @ 9:52 AM PDT

Niiiiiiiiiiiceeee :D

I'll try to use and adapt this in my Zsh as well. Thanks a ton for this tip!

Matija "hook" Šuklje
Quoth Matija "hook" Šuklje on September 11, 2010 @ 9:39 PM PDT

Hmmmm, is there a trick to make it work with a predefined prompt style?

I don't get those nifty semaphores and branches if I use a e.g.:

prompt adam2
Brian
Quoth Brian on September 12, 2010 @ 3:29 AM PDT

No idea, I haven't messed much with the pre-packaged themes.

Matija "hook" Šuklje
Quoth Matija "hook" Šuklje on September 12, 2010 @ 4:19 AM PDT

Your roll your own then?

Hmmm, maybe I should as well. It'd be about time.

Reader
Quoth Reader on September 12, 2010 @ 6:59 AM PDT

Traffic lights, now that is epic.

Noah
Quoth Noah on September 26, 2010 @ 3:46 PM PDT

Changing the charset to UTF-8 in PuTTY might help, if you haven't done that already.

Kevin Colyar
Quoth Kevin Colyar on October 07, 2010 @ 6:58 AM PDT

You should check out oh-my-zsh.

http://github.com/robbyrussell/oh-my-zsh

Has all sorts of themes, and most have git status.

theosp
Quoth theosp on October 07, 2010 @ 3:40 PM PDT

Using the PROMPT_COMMAND variable this can be reproduce in BASH.

I will hopefully implement it in today (unless someone will do it before me, in which case, please leave a note here)

Bjoern
Quoth Bjoern on October 07, 2010 @ 6:48 PM PDT

Thanks for posting this, very interesting! Here is my modified prompt using your snippet. e.g. Normal it looks something like this (white/green combination)

[2:42][user@machine:~]% cd ..

[2:43][user@machine:/home]%

And thanks to your vcs_info code:

[2:44][user@machine:RepoDir][repo]%

PROMPT='[%F{green}%B%T%b][%F{green}%B%n@%m%F{white}%b:%c${vcs_info_msg_0_}%F{blue}%(?/%F{blue}/%F{red})% %F{white}]%% '

theosp
Quoth theosp on October 09, 2010 @ 10:57 AM PDT

Here's a bash implementation:

http://gist.github.com/618792

Peter Aronoff
Quoth Peter Aronoff on October 09, 2010 @ 11:46 AM PDT
grizz
Quoth grizz on October 15, 2010 @ 4:41 AM PDT

There is my version (nice especially for two line prompt). /Based on Floriana Kriener's version/

http://grizz.pl/zsh_i_git_branch_i_zmiany [Polish language, but listing with english comments)

grizz
Quoth grizz on October 15, 2010 @ 4:42 AM PDT

ahh markdown ;) clickable links...

http://grizz.pl/zsh_i_git_branch_i_zmiany

Jerry H.
Quoth Jerry H. on October 17, 2010 @ 3:10 PM PDT

No matter what I set stagedstr and unstagedstr to %c always resolves to the current directory name and %u resolves to nil.

Anybody have an idea what I might be doing wrong?

Matija "hook" Šuklje
Quoth Matija "hook" Šuklje on October 22, 2010 @ 3:04 AM PDT

It took me quite some time, but now I've finnally hacked up my own Zsh prompt.

Thank you, Brian, for the inspiration and the Git solution.

Avram Dorfman
Quoth Avram Dorfman on March 11, 2011 @ 3:45 AM PST

grrrr... typed a nice detailed message and forgot to type the captcha...

Has anyone got this working in Mac OS X?

For me the %c and %u do what someone said above, and I don't get any traffic lights no matter what I do.

Avram Dorfman
Quoth Avram Dorfman on March 11, 2011 @ 11:04 AM PST

Ah-hahah. Sweet, I got it working.

The reason %u and %c were not working for me is that Mac OS X (10.6.6)'s built-in zsh is version 4.3.9, which does not support the check-for-changes option (note: this information was not forthcoming - no mention in the release notes - I had to download the 4.3.11 and 4.3.9 zsh source tarballs and do a global search to determine this).

With that information, I installed 4.3.11 and set it as my default shell.

Now the above solutions works, including the traffic lights.

Avram Dorfman
Quoth Avram Dorfman on March 11, 2011 @ 11:07 AM PST

Oh, I should also mention - I had to change my terminal windows to use UTF-8 character encoding to get the bullets to actually show up as bullets instead of wonky characters with foreign accents on them.

Speak your Mind

You can use Markdown in your comment.
Email/URL are optional. Email is only used for Gravatar.

Preview