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
Adding this to ~/.bashrc
:
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
The parse_git_branch
function will return the current git branch if we are currently in a git repo directory, otherwise it will return empty string.
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
PS1 stands for Prompt String 1. It is the one of the prompt available in Linux/UNIX shell. When you open your terminal, it will display the content defined in PS1
variable in your bash prompt.
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
We use this sequence \[\e[32m\]
to set the color of the text goes after that sequence, until another color is set. In this sequence, \[
and \]
are used to mark the start and end of non-printing characters. Between them, \e
denotes an ASCII escape character, and follows by [32m
, which is the actual color code.
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: