git status in shell prompt

April 24, 2008 – 1:24 pm

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.

  1. One Response to “git status in shell prompt”

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

    By is on Jul 13, 2008

Post a Comment