Minimal Git Bash prompt

I'm keen on taking a minimalist approach when it comes to using external dependencies (KISS principle). And when we talk about a Bash prompt spiced up with some Git information, i don't want dozens of fancy icons and distracting information i rarely use. Really, who is using the number of commits diverged from the remote tracking branch all the time he is looking at his prompt? Or if the current commit has been pushed to the remote already? Every time? No kidding! Just scrap this bloatware and make your prompt fast again!

While working with Git, the only really useful information to be shown inside your prompt is the current state of Gits HEAD pointer:

  • where it points to (either branch name or commit itself if in detached HEAD state)
  • and if your working tree or index diverged from the commit to which HEAD points to (because this prevents you from moving HEAD without stashing, committing or resetting your working tree)


All the rest can be shown by Git commands when you need this information. You can create aliases to further dampen down the command length if thats your argument against typing it in.

Now there are lots of bloated prompt scripts out there with lots of configuration options and why something simple like a prompt enhancement has to be kept in its own repository with its own revision history is beyond me. That's contrary to KISS and if it's simple, i can adjust it myself directly in the source without the need for configuration options. So I'm looking for something to copy and paste. As a best case just a variable which i can put into my PS1 variable of Bash. Even the __git_ps1 from git-prompt.sh, which comes prepackaged with most default Git installations, is too bloated for my taste of how simple such a task is meant to be.

The simple copy 'n paste solution


After fiddling with other's scripts i came to my own solution which i share here. Add the following lines to your .bashrc file.

# bash color escape sequences
color_red=$'\001'$(tput setaf 1 2>/dev/null || echo $'\e[31m')$'\002'
color_green=$'\001'$(tput setaf 2 2>/dev/null || echo $'\e[32m')$'\002'
color_blue=$'\001'$(tput setaf 4 2>/dev/null || echo $'\e[34m')$'\002'
color_reset=$'\001'$(tput sgr 0 2>/dev/null || echo $'\e[0m')$'\002'

# dereference git symbolic reference HEAD to get branch name or sha1 of commit
# object and amend by information about current status of staging area
dereference_git_HEAD() {
    local sha1
    sha1=$(git rev-parse --short HEAD 2>&1)
    if [ $? -eq 0 ]; then
        local color_symref=$color_green
        local color_ref=$color_blue
        local dirty=$(git status --porcelain 2>&1)
        if [ ! -z "$dirty" ]; then
            color_symref=$color_red
            color_ref=$color_red
            dirty='*'
        fi
        GIT_HEAD_PROMPT="$color_symref($(git symbolic-ref --quiet --short HEAD)$dirty)$color_reset"
        if [ $? -ne 0 ]; then
            GIT_HEAD_PROMPT="$color_ref[$sha1$dirty]$color_reset"
        fi
    else
        GIT_HEAD_PROMPT=""
    fi
}

# run command before bash takes PS1 to build prompt
PROMPT_COMMAND="dereference_git_HEAD; $PROMPT_COMMAND"

Now there is this simple variable GIT_HEAD_PROMPT available. And it contains all i want. Even strictly correct escaped color sequences which do not mangle up your prompt on overlong lines. You can't imagine how many of the Git Bash prompt scripts out there forget to handle that accordingly.

Use this variable in .bashrc now

PS1='\u@\h:\w$GIT_HEAD_PROMPT$> '

and your Bash prompt becomes this:

user@host:~/$> cd Git_repository
user@host:~/Git_repository(master)$> git checkout 4483c9f
user@host:~/Git_repository[4483c9f]$> vi README
user@host:~/Git_repository[4483c9f*]$> git commit -a -m 'added info'
user@host:~/Git_repository[654750b]$> git checkout -b new_branch
user@host:~/Git_repository(new_branch)$> touch NEWFILE
user@host:~/Git_repository(new_branch*)$> cd ..
user@host:~/$>

Hooray. Task resolved!

This article is my oldest. It is 562 words long, and it’s got 0 comments for now.