My variation of Git branch in bash prompt

 06 Mar 2009

 0 Comments

After reading another cool blog post about putting your current git branch in your bash prompt I decided I needed to try this out. Once I got it working I added in color coding to see the status of the current checkout as well!

First off, you need bash-completion and git installed on your server (bash-completion and git-core on Debian/Ubuntu). Once installed you can enable bash completion in the system wide bash file (/etc/bash.bashrc) or in your own ~/.bashrc by adding these lines (Clearly if you are not on Debian/Ubuntu double check file paths):

# Completion

if [ -f /etc/bash_completion ]; then

    . /etc/bash_completion

fi

Once this is all set you should have a function called __git_ps1 available. Try it out by just running “__git_ps1” on your command line from a git repo. You should get the branch name returned inside parenthesis’s.

Now comes my variations on how to include this in your prompt. My entire ~/.bash_prompt file can be found on my git repo. I source this file into my ~/.bashrc. The two most interesting parts are the function that determines the color of the branch based on git-status output and the function that gets the branch name. Branch name is pretty simple. We check that the __git_ps1 function is available and if it is, check that we’re in a branch using it. If we are we echo the branch name. Pretty clean.

prompt_git_branch() {

    if type -p __git_ps1; then

        branch=$(__git_ps1 '%s')

        if [ -n "$branch" ]; then

            echo -e "$branch"

        fi

    fi

}

The next function has to grep stuff out of git status to determine what state the repo is in. If we are completely up to date we use green. If I have local changes it’s blue. If we have files in our index ready to be committed I use red. This is really great with my home directory cause it helps remind me to add new dotfiles that I don’t care about to .gitignore (or commit them if they should be public config files).

prompt_git_branch_color() {

    if type -p __git_ps1; then

        branch=$(__git_ps1 '%s')

        if [ -n "$branch" ]; then

            status=$(git status 2> /dev/null)



            if $(echo $status | grep 'added to commit' &> /dev/null); then

            # If we have modified files but no index (blue)

                echo -e "\033[1;34m"

            else

                if $(echo $status | grep 'to be committed' &> /dev/null); then

                # If we have files in index (red)

                    echo -e "\033[1;31m"

                else

                # If we are completely clean (green)

                    echo -e "\033[1;32m"

                fi

            fi

        fi

    fi

}

It took some playing but I finally found the right final line to correctly tell bash which characters in the prompt are visible. If anyone has a good way of making these functions smaller or faster I’d love to hear it. I had some trouble making sure that the functions were always executed (not just on a new shell’s creation, but on every display of PS1). The delay this causes is not noticeable on all of my computers but more speed never hurts.