A bash prompt with git status

So you want to be fancy? (Updated)

One of the great things about *NIX in general is the power of the command prompt. And the ability to customise it, like so:

git-prompt

I've seen all sorts of ways to do this, including the use of powerline, which is ab-so-bloody-lute-ly overkill for a prompt. Seriously. What is wrong with you? It's overkill for vim too. No, shhh, go back whence you came traveler.

A little while ago I came across a a .bashrc which had a PROMPT_COMMAND whose duty was to present information to the user on the state of the git repo in the cureent working directory. It was rather neat but the code was about three times longer than it needed to be, and that deeply offended my sensibilities... So I wrote a nice compact version which is below.

# get current status of git repo
function parse_git_dirty {
  STATUS="$(git status 2> /dev/null)"
  if [[ $? -ne 0 ]]; then printf "-"; return; else printf "["; fi
  if echo ${STATUS} | grep -c "renamed:"         &> /dev/null; then printf ">"; else printf ""; fi
  if echo ${STATUS} | grep -c "branch is ahead:" &> /dev/null; then printf "!"; else printf ""; fi
  if echo ${STATUS} | grep -c "new file::"       &> /dev/null; then printf "+"; else printf ""; fi
  if echo ${STATUS} | grep -c "Untracked files:" &> /dev/null; then printf "?"; else printf ""; fi
  if echo ${STATUS} | grep -c "modified:"        &> /dev/null; then printf "*"; else printf ""; fi
  if echo ${STATUS} | grep -c "deleted:"         &> /dev/null; then printf "-"; else printf ""; fi
  printf "]"
}

parse_git_branch() {
  # Long form
  git rev-parse --abbrev-ref HEAD 2> /dev/null
  # Short form
  # git rev-parse --abbrev-ref HEAD 2> /dev/null | sed -e 's/.*\/\(.*\)/\1/'
}

__export_ps1() {
  export PS1="\n[\033[32m\]\w\033[00m\]] (\033[33m\]\$(parse_git_branch)\[\033[31m\]\$(parse_git_dirty)\[\033[00m\]) \n[\u@\h]$ "
}
__export_ps1
PROMPT_COMMAND='__export_ps1'

So if you want a prompt that shows some details on the status of your git repos and the branch you are working on (that has been a life-saver a few times already) then paste the code above in to your ~/.bashrc at the end.

If you only care for the last section of the git branch path for eg: feature/new-thing will become new-thing, then uncomment (and comment out) the relevant part in parse_git_branch().

And of course, customise away!

Edit: updated to remove the 6 calls to git, reducing overhead. Thanks to @dwagenk on fosstodon.org for reminding me.