There are a lot of blog posts describing techniques of putting your current git branch in your bash prompt. After reading one of those posts more then year ago I immediately edited my ~/.bash_profile
and was very happy until very recent, when I have started using --color
argument with git commands. Surprisingly to me colors made me so much more effective that I quickly tweaked my git config: git config --global color.ui auto
This allowed my to have colors everywhere by default. Shortly after I got an idea that colors in prompt may be used for displaying a status of the working tree / index.
Motivation
I really wanted to try that idea out, because I thought it was a chance to solve a problem that bugged me for years already. I was looking for a way to remind myself to commit more often, since I tempt to commit only after I’m done with a task and it’s hard to imagine how many times I regretted that!!
Design
So my plan was to display “current git branch” in a bash prompt in a different color depending on a state of the working tree / index:
- No changes
- Untracked files
- Stashed changes
- Modified files
- Deleted files
Implementation
I wont bother you with a details on how to get a “current git branch” since there are lots of posts about it, instead I’ll focus your attention on snippet that parses git status and adds colors:
txtblk='\033[0;30m' # Black - Regular
txtred='\033[0;31m' # Red
txtgrn='\033[0;32m' # Green
txtylw='\033[0;33m' # Yellow
txtblu='\033[0;34m' # Blue
txtpur='\033[0;35m' # Purple
txtcyn='\033[0;36m' # Cyan
txtwht='\033[0;37m' # White
bldblk='\033[1;30m' # Black - Bold
bldred='\033[1;31m' # Red
bldgrn='\033[1;32m' # Green
bldylw='\033[1;33m' # Yellow
bldblu='\033[1;34m' # Blue
bldpur='\033[1;35m' # Purple
bldcyn='\033[1;36m' # Cyan
bldwht='\033[1;37m' # White
unkblk='\033[4;30m' # Black - Underline
undred='\033[4;31m' # Red
undgrn='\033[4;32m' # Green
undylw='\033[4;33m' # Yellow
undblu='\033[4;34m' # Blue
undpur='\033[4;35m' # Purple
undcyn='\033[4;36m' # Cyan
undwht='\033[4;37m' # White
bakblk='\033[40m' # Black - Background
bakred='\033[41m' # Red
badgrn='\033[42m' # Green
bakylw='\033[43m' # Yellow
bakblu='\033[44m' # Blue
bakpur='\033[45m' # Purple
bakcyn='\033[46m' # Cyan
bakwht='\033[47m' # White
txtrst='\033[m' # Text Reset
__vcs_status() {
if type -p __git_ps1; then
branch=$(__git_ps1)
else
branch=$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/')
fi
if [ $branch ]; then
# not updated
color="${txtpur}"
status=$(git status --porcelain 2> /dev/null)
# if we have non untracked files (blue)
if $(echo "$status" | grep '?? ' &> /dev/null); then
color="${txtblu}"
fi
# added to index (green)
if $(echo "$status" | grep '^A ' &> /dev/null); then
color="${txtgrn}"
fi
# updated in index (Cyan)
if $(echo "$status" | grep '^ M ' &> /dev/null); then
color="${txtcyn}"
fi
# deleted from index (red)
if $(echo "$status" | grep '^ D ' &> /dev/null); then
color="${txtred}"
fi
echo -e $color
fi
}
I am not that good at bash and I would be more then happy to hear your your suggestions how to make implementation smaller or faster. Any other suggestions or comments are also very welcome.
Finally if you want to see full implementation check out my git repo.