git status in shell prompt

When I see the post "Current Git Branch in Bash Prompt" from reddit, I found it really a cool idea. Personally, I use zsh, though that post is about bash, adding similar thing to zsh is pretty easy!

My zsh prompt is already pretty cool in my opinion. I borrowed something from Phil!'s ZSH Prompt, but I prefer a much cleaner style. Here's what it looks like normally:

normal.png

It shows the current username and current working directory. I don't like the full path of cwd shown in the prompt because I don't care about it most of the time. Note the title bar below is not really irb, it's the Screen status line. :p

When the last command failed with a non-zero exit code, or when I switched to root, there will be some changes in the prompt:

error-code.png

Now it will also show the branch name if in a git repository:

git-branch.png

What's even cooler is that it will also show how many files you've modified in the git repo:

git-modification.png

Notice the yellow number "1" in the prompt. So here's my prompt:


autoload colors zsh/terminfo
if [[ "$terminfo[colors]" -ge 8 ]]; then
    colors
fi

precmd () { if [[ "$TERM" = "dumb" ]] then prompt='%(?..(%?%))%n@%1/ %(!.#.$) ' else local P_GREEN="%{$terminfo[bold]${fg[green]}%}" local P_CLEAR="%{$terminfo[sgr0]%}" local P_ERROR="%{$terminfo[bold]${fg[red]}%}%(?..(%?%))$P_CLEAR" local P_USER="%(!.${bg[green]}${fg[black]}ROOT.%n)$P_CLEAR@" local P_DIR="%1/" local P_PRO=" %(!.#.$) " local P_TITLE local GIT_BRANCH=`git-branch 2>/dev/null | sed -n '/^* /s/^* //p'` if [[ ! -z "$GIT_BRANCH" ]]; then local GIT_MODIFIED=`git-status 2>/dev/null | egrep -c '^#\s*(new file|modified|deleted|copied|renamed|typechange|unknown|unmerged):'` if [[ $GIT_MODIFIED > 0 ]]; then GIT_MODIFIED=":%{${fg[yellow]}%}$GIT_MODIFIED$P_CLEAR" else GIT_MODIFIED="" fi GIT_BRANCH="%{$terminfo[bold]%} ($GIT_BRANCH$GIT_MODIFIED)$P_CLEAR" fi if [[ "$TERM" = "screen" ]]; then P_TITLE=$'%{\ek%1/\e\\%}' elif [[ "$TERM" = "xterm" ]]; then if [[ -z "$DTACH" ]]; then P_TITLE=$'%{\e]0;%1/\a%}' else P_TITLE=$'%{\e]0;[%1/]\a%}' fi else P_TITLE="" fi prompt="$P_ERROR$P_USER$P_GREEN$P_DIR$P_CLEAR$GIT_BRANCH$P_PRO$P_TITLE" fi }

However, maybe git-status can be a little slow sometimes. Maybe there're some lower level (and faster) command that can be used to count modifications.

Comments (1)

is July 13, 2008
啊哈哈,你这个做法真是挺,变态的,回头我也去试试,好像蛮酷的.