Groesbeek, view of the 'National Liberation Museum 1944-1945' in Groesbeek. © Ton Kersten
Fork me on GitHub

git status in the prompt

2012-07-23 (124) by Ton Kersten, tagged as code, git, linux, sysadm

Working with git a lot I decided I needed some git status in my prompt.

I searched the web and some solutions where almost what I wanted and this one by Sebastian Celis came very close.

But it didn't work with my version of zsh, because that didn't seem to understand the =~ operator.

I also think Sebastian makes things over complicated and so I changed some things aroud.

This is what I came up with:

First make sure this code is included in your ~/.zshenv file

prompt_git_info()
{
    unset __GIT_BRANCH
    unset __GIT_BRANCH_STATUS
    unset __GIT_BRANCH_DIRTY

    local st="$(git status 2>/dev/null)"
    if [[ -n "$st" ]]; then
        local -a arr
        arr=(${(f)st})

        if [[ $arr[1] = *Not\ currently\ on\ any\ branch.* ]]
        then
            __GIT_BRANCH='no-branch'
        else
            __GIT_BRANCH="${arr[1][(w)4]}"
        fi

        if [[ $arr[2] = *Your\ branch\ is* ]]
        then
            if [[ $arr[2] = *ahead* ]]
            then
                __GIT_BRANCH_STATUS='ahead'
            elif [[ $arr[2] = *diverged* ]]
            then
                __GIT_BRANCH_STATUS='diverged'
            else
                __GIT_BRANCH_STATUS='behind'
            fi
        fi

        if [[ $st = *nothing\ to\ commit* ]]
        then
            __GIT_BRANCH_DIRTY='0'
        else
            __GIT_BRANCH_DIRTY='1'
        fi
    fi

    if [[ -n "$__GIT_BRANCH" ]]
    then
        local s="("
        s+="$__GIT_BRANCH"
        case "$__GIT_BRANCH_STATUS"
        in
            ahead)      s+="↑"  ;;
            diverged)   s+="↕"  ;;
            behind)     s+="↓"  ;;
        esac
        if [[ "$__GIT_BRANCH_DIRTY" = "1" ]]
        then
            s+="⚡"
        fi
        s+=")"

        printf " %s%s" "%{${fg[yellow]}%}" $s
    fi
}

and set your prompt to something like this

PS1=$'$C_CYAN%n@%m$(prompt_git_info) $C_WHITE%2~$ $C_OFF'

When I now switch to a directory that is under control of git I get gt status messages in my prompt, like

tonk@mach (master) ~/dir$ git commit -a
[master fca5ac3] Nice, new stuff.
 6 files changed, 88 insertions(+), 12 deletions(-)
tonk@mach (master) ~/.dir$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)
tonk@mach (master) ~/.dir$