How to show current git branch with colors in Bash prompt

Adding current git branch name in Bash prompt with highlighted color can help to avoid a lot of problems with working on wrong git branches, which is a quite popular scenario to most of the developers sometime. This guide show to do it and explain some underneath concept of the hack.

A quick hack

parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
export PS1="\u@\h \[\e[32m\]\w \[\e[91m\]\$(parse_git_branch)\[\e[00m\]$ "

Restart the terminal, or source ~/.bashrc, and it works:

TL; DR

Parse git branch

In this function, git branch command will be used. This command will list of local git branches with the * symbol before the current branch:

If we are not in a git repo directory, the command will output something like this to stderr:

We surely don’t want this to appear in our prompt, so we redirect the stderr to /dev/null with this: 2> /dev/null

The last part is using sed command to extract the current branch name (the line starting with symbol *) from the git branch output.

git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'

Where -e '/^[^*]/d' will delete all lines that do not start with symbol *, and the -e 's/* \(.*\)/(\1)/' will replace (substitute) the current branch line (with symbol * and a space at the beginning) with the branch name, putting it in a pair of bracket ().

What is PS1 variable

Example of a PS1 string:

To change this prompt, just set new value to PS1 string, for example: PS1='\u@\h \w > '

Where \u, \h and \w are control commands for PS1 string, which stand for username of the current user, the hostname and the current working directory respectively.

Available control commands for PS1 string:

d - the date in "Weekday Month Date" format (e.g., "Tue May 26")
e - an ASCII escape character (033)
h - the hostname up to the first .
H - the full hostname
j - the number of jobs currently run in background
l - the basename of the shells terminal device name
n - newline
r - carriage return
s - the name of the shell, the basename of $0 (the portion following the final slash)
t - the current time in 24-hour HH:MM:SS format
T - the current time in 12-hour HH:MM:SS format
@ - the current time in 12-hour am/pm format
A - the current time in 24-hour HH:MM format
u - the username of the current user
v - the version of bash (e.g., 4.00)
V - the release of bash, version + patch level (e.g., 4.00.0)
w - Complete path of current working directory
W - the basename of the current working directory
! - the history number of this command
# - the command number of this command
$ - if the effective UID is 0, a #, otherwise a $
nnn - the character corresponding to the octal number nnn
\ - a backslash
[ - begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt
] - end a sequence of non-printing characters

How to set the colors

All the color codes can be referred here: https://misc.flogisoft.com/bash/tip_colors_and_formatting

So, in our hack:

export PS1="\u@\h \[\e[32m\]\w \[\e[91m\]\$(parse_git_branch)\[\e[00m\]$ "

the command prompt will start with username@host and a space (\u@\h ), in default terminal color (normally, white text on black background).

Then comes \[\e[32m\]\w — current working directory (\w) in green ([32m) color, and a space.

Next is current git branch (\$(parse_git_branch)) if we are in a git repo, in light red ([91m) color.

The last part of the prompt is symbol $ in default ([00m) color.

Final result is as following:

References