Friday, 4 May 2018

Git branch information in your bash prompt

I saw a post the other day by Barry McGillin about improving bash to include repository information - see here: I had seen similar behaviour using zsh - specifically when I had tried out the oh-my-zsh project, but I always find my self turning back to bash.

So, I started doing some searching on how to achieve this in bash to see what other options there were - and I found a few articles basically with the same solution as in the post I found. Then I came across the fact that Git provides a script that can be leveraged to accomplish the same. You can view the script hosted on GitHub:

The header of the script includes instructions on how to leverage this file, which in a nutshell is to place the script somewhere on your system, sourcing it within your .bashrc file, and updating your PS1 variable, again in bashrc, to reference __git_ps1.

Since I already had git installed, I thought I'd just look to make sure it exists on my installed version. So I ran the following search:

trent@birroth:~$ dpkg -L git | grep prompt

And digging into the script, I see that /usr/lib/git-core/git-sh-prompt is effectively the same script referenced above. I also found I didn't need to copy that script anywhere, so it must be already sourced elsewhere.

Within that script, the suggestion is to make PS1 look like:

PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '

What I didn't like about this is that it only included the current folder you are in, whereas my original PS1 prompt includes the full path, or relative to home if within my home directory. So, I found out that I can just append my existing PS1 variable with $(__git_ps1) to include branch information when the current folder is within a Git repository.

So, my default PS1 included colours so is quite a bit longer - but to include this, my full PS1 then became:

PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]$(__git_ps1)\$ '

This above is actually in a conditional block, one for the non-colour option - I'm sure you can figure out how to add the relevant section in.

With that then, my prompt then became:

Which shows the branch I'm on.

Some other options to provide more feedback about the state of the branch/folder, as described in the script:

  • GIT_PS1_SHOWDIRTYSTATE: shows a * for unstaged files; a + for staged files
  • GIT_PS1_SHOWSTASHSTATE: shows a $ if something is stashed
  • GIT_PS1_SHOWUNTRACKEDFILES: shows a % if something is not being tracked
  • GIT_PS1_SHOWUPSTREAM: with a value of auto, shows < when you are behind, > when you are ehad, <> when you have diverged, = when there are no differences. There are some more options for this - but I suggest you review the script linked earlier for more details.

If you're not in a git repository, your prompt will just display without the Git portion as you would hope and expect.