Skip to content

Instantly share code, notes, and snippets.

@sbilstein sbilstein/bash_prompt
Last active Dec 31, 2015

Embed
What would you like to do?
BASH prompt with git branch name and status. Fixed to handle directory names with spaces and checks to see if nested directories are under source control.
#!/bin/bash
# BASH prompt builder
#
# This is a script I use to generate BASH prompts that look like this:
# (master)*
# [sbilstei@sbilstei-mn1:~/localcode/git-sandbox]:$
#
# Basically user, the machine's hostname, current working directory tilde condensed and an optional branch name
# when navigating a git repo. The asterisk is visible if there are uncommitted changes.
#
# To use this script add the following lines to your .bash_profile:
#
# function prompt_command {
# export PS1=$(<scriptlocation>)
# }
# export PROMPT_COMMAND=prompt_command
#
# where <scriptlocation> is the location of this script. You will also need to set execute permissions on the script by typing:
# chmod 744 <script>
# By tying the execution of this script to PROMPT_COMMAND
# we can guarantee that the branch status gets updated on every new prompt. Check out this SO post on the
# topic: http://stackoverflow.com/a/11107564/608801
#
function git_changed {
if [ ! -z "$(git diff-index --name-only HEAD --)" ]; then
echo "*"
fi
}
# Substitute a leading path that's in $HOME for "~"
function pwd_short {
local dir="$PWD"
if [[ "$HOME" == ${dir:0:${#HOME}} ]] ; then
dir="~${dir:${#HOME}}"
fi
echo "${dir}"
}
function git_branch_and_status {
local maxlen=30
local truncatelen=maxlen-3
local is_repo=$(git rev-parse --is-inside-work-tree 2> /dev/null)
if [ "$is_repo" = "true" ]; then
ref=$(git symbolic-ref HEAD 2> /dev/null)
local branch=${ref#refs/heads/}
namelength=${#branch}
if [ $namelength -gt $maxlen ]; then
branch="${branch:0:${truncatelen}}..."
else
branch="${branch}"
fi
echo "(${branch})$(git_changed)\n"
else
echo ""
fi
}
echo -e "$(git_branch_and_status)[$USER@$HOSTNAME:$(pwd_short)]$ "
@TwoLivesLeft

This comment has been minimized.

Copy link

TwoLivesLeft commented Dec 16, 2013

You might want to wrap "$(git diff-index --name-only HEAD --)" in double quotes, otherwise this script does not handle working directories containing spaces.

@joeyyang

This comment has been minimized.

Copy link

joeyyang commented Dec 16, 2013

I got this to work by saving this as an (extensionless) file in my ~/bin directory ("bash_prompt"), then by placing the below code in my /.bash_profile, replacing "< scriptlocation >" below with "/bin/bash_prompt

function prompt_command {
   export PS1=$(<scriptlocation>)
 }
 export PROMPT_COMMAND=prompt_command 
@kevinkyyro

This comment has been minimized.

Copy link

kevinkyyro commented Dec 16, 2013

My prompt would be achieved by increasing maxlen (my branch and pwd are on their own line so I don't bother truncating them) and changing the last line to:

echo -e "\n(\w)-[$(git_branch_and_status)]\n\u@\h-[\D{%H:%M}]$ "

The effect is:

                                          # intentional newline        
(~/path/to/repo)-[JIRA-42-branch-name]    # pwd and branch
user@host-[12:40]$                        # prompt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.