Show GIT status on bash prompt

It's been a while since I last post, so I'm quite surprised by the new blogger interface. Guess it's all because of Google+ integration :p

I've been using git for quite a while, and it's by far the best VCS I've ever used. The thing is, when you have a lot of branches in you project,it's really hard to keep track of what branch you are on. It would be nice to have a indicator or something that tell you just that. I've seem people using Fish shell. With Fish shell, you can simply write a ruby script to customize the prompt text, showing git status is just one of the things you can do. But since I never get used to Fish shell and at that time my projects never went over two branches, I didn't think it's necessary. Recently I am working on some projects that requires 3 to 4 branches, so I sometimes commit/edit on the wrong branch. That's when I decided to add git status to my prompt.

Going through the bash manpage I found that a variable called PROMPT_COMMAND may just do the trick. The command specified by PROMPT_COMMAND will be called just before every prompt is showed. Changing the PS1 variable on-the-fly every time enable us to show pretty much anything we want. Here's what I did:

My PS1 variable is:
export PS1="\[\e[1;37m\][\[\e[0m\]\[\e[1;33m\]\[email protected]\h\[\e[0m\] [\e[1;34m\]\W\[\e[0m\]\[\e[1;37m\]]\$\[\e[0m\] "

Now I add the following lines to my '~/.bashrc':
# Pre-prompt callback
pre_prompt() {
  status=`git status 2> /dev/null`
  check=`echo $status | grep -i 'branch'`
  cancommit=`echo $status | grep -i 'to be committed'`
  notstage=`echo $status | grep -i 'not staged'`

  if [ -n "$check" ]; then
    if [[ "$check" == *Not* ]]; then
      branch=`echo $check | cut -d ' ' -f 4`
    if [ -n "$notstage" ]; then
    elif [ -n "$cancommit" ]; then
    export PS1="\[\e[1;37m\][\[\e[0m\]\[\e[1;33m\]\[email protected]\h\[\e[0m\] \[\e[1;34m\]\W\[\e[0m\] \[\e[1;32m\]($branch)\[\e[0m\]\[\e[1;37m\]]\$\[\e[0m\] "
    export PS1=$PS1_ORIG

export PS1_ORIG=$PS1
export PROMPT_COMMAND=pre_prompt

As you can see, the PRMOPT_COMMAND variable is set to the 'pre_prompt' function. In this function, I check git status and update PS1. Notice that the 'check' variable is used to determine whether you are in a git repo or not. If not, it will just restore the original PS1 variable.

Note that the text between parentheses shows your current branch. If you not currently on any branch, it's set to 'none'. If the repository is not clean, there will be an extra '#' or '*' right next to the branch name. If there are changes that are not staged, '*' is append to the branch name; else if all changes are staged, '#' is appended.

Here's what my prompt looks like now, have fun :P



嘸蝦米文翻譯機 網頁版

[教學] 在GMail 收台大Web Mail信件

Q445: Marvelous Mazes