Andy Lester

Technology, careers, life and being happy

My bash prompt with git/svn branch+status display

| 2 Comments

After spending a few hours last night switching between three different branches in the ack2 project, and typing “git br” over and over, I decided I needed to put branch status in my bash prompt. The only question was: Which one would I steal? Fortunately, Rob Hoelz was online and I mentioned it to him and he handed me his, so I stole it and also added Subversion support as well.

Note: Edited to fix a problem with detecting SVN branches.

#!/bin/bash

# Adapted from from https://github.com/hoelzro/bashrc/blob/master/colors.sh

function __prompt
{
    # List of color variables that bash can use
    local BLACK="\[\033[0;30m\]"   # Black
    local DGREY="\[\033[1;30m\]"   # Dark Gray
    local RED="\[\033[0;31m\]"     # Red
    local LRED="\[\033[1;31m\]"    # Light Red
    local GREEN="\[\033[0;32m\]"   # Green
    local LGREEN="\[\033[1;32m\]"  # Light Green
    local BROWN="\[\033[0;33m\]"   # Brown
    local YELLOW="\[\033[1;33m\]"  # Yellow
    local BLUE="\[\033[0;34m\]"    # Blue
    local LBLUE="\[\033[1;34m\]"   # Light Blue
    local PURPLE="\[\033[0;35m\]"  # Purple
    local LPURPLE="\[\033[1;35m\]" # Light Purple
    local CYAN="\[\033[0;36m\]"    # Cyan
    local LCYAN="\[\033[1;36m\]"   # Light Cyan
    local LGREY="\[\033[0;37m\]"   # Light Gray
    local WHITE="\[\033[1;37m\]"   # White

    local RESET="\[\033[0m\]"      # Color reset
    local BOLD="\[\033[;1m\]"      # Bold

    # Base prompt
    PS1="$LCYAN\h:$YELLOW\w$LCYAN \\\$$RESET "

    local dirty
    local branch

    # Look for Git status
    if git status &>/dev/null; then
        if git status -uno -s | grep -q . ; then
            dirty=1
        fi
        branch=$(git branch --color=never | sed -ne 's/* //p')

    # Look for Subversion status
    else
        svn_info=$( (svn info | grep ^URL) 2>/dev/null )
        if [[ ! -z "$svn_info" ]] ; then
            branch_pattern="^URL: .*/(branch(es)?|tags)/([^/]+)"
            trunk_pattern="^URL: .*/trunk(/.*)?$"
            if [[ $svn_info =~ $branch_pattern ]]; then
                branch=${BASH_REMATCH[3]}
            elif [[ $svn_info =~ $trunk_pattern ]]; then
                branch='trunk'
            else
                branch='SVN'
            fi
            dirty=$(svn status -q)
        fi
    fi

    if [[ ! -z "$branch" ]]; then
        local status_color
        if [[ -z "$dirty" ]] ; then
            status_color=$LGREEN
        else
            status_color=$LRED
        fi
        PS1="$LCYAN($BOLD$status_color$branch$LCYAN)$RESET $PS1"
    fi
}

if [[ -z "$PROMPT_COMMAND" ]]; then
    PROMPT_COMMAND=__prompt
else
    PROMPT_COMMAND="$PROMPT_COMMAND ; __prompt"
fi
__prompt

Just drop that into your ~/.bash directory as prompt.sh, and then add

source ~/.bash/prompt.sh

to your .bashrc. Now you have color-coded branch names: red for dirty, green for clean.

2 Comments

  1. Great script! I tweaked it a bit to show bzr status as well. Virtually the same commands as svn, except for a couple of items.

    The dirty flag needs to be set like this:
    dirty=$(bzr status -SV)

    And the patterns need to be matched dependent on your repo scheme. For ours, this is what we use:

    trunk_pattern=”^ checkout of branch: .*/trunk/$”
    branch_pattern=”^ checkout of branch: .*/feature/([^/]+)”

    And we also have a release branch, so I added this one:
    release_pattern=”^ checkout of branch: .*/release/([^/]+)”

    And you have to set the branch like this instead:
    branch=${BASH_REMATCH[1]}

    Finally, there’s a small typo in the Bold color; it should be this:
    local BOLD=”\[33[1m\]”
    instead of
    local BOLD=”\[33[;1m\]”

    Thanks for ack! and the other great content you post!

  2. Cool tips. However there is typo in it, If I am not mistaken.

    The line:
    branch=$(git branch –color=never | sed -ne ‘s/* //p’)

    should be like:

    branch=$(git branch –no-color | sed -ne ‘s/* //p’)

    Best Regards,
    Mohammad S Anwar

Leave a Reply

Required fields are marked *.