Today I finally got my git environment working to my satisfaction on my MacBook Pro. First as I migrated to Mac OS X, I thought I would need a graphical tool for gitl like gitx or gity or even some sort of commercial GUI. After some experimenting with the different GUIs and many oddities I ran into, I just switched back to the good old command line, as I was used to on the Linux installations at the university. But still, there were several annoying issues I didn’t had on ubuntu/SuSE installations or which just would be nice to have. I want to discuss 2 issues in the following post:

  • No bash integrated information about the current branch, commit and difference between origin and local repository, etc. In short: No git status in the prompt
  • No tab completion


First of all lets enable tab completion in git. To do so you just have to do some scripting in your .bash_profile. But first you have to download the bash completion script from the git source base to your home directory:

cd
curl https://github.com/git/git/raw/master/contrib/completion/git-completion.bash -O

Now you just have to source that file in your bash_profile. While editing your bash profile you can also add some lines to show your current git status in your prompt. First the sourcing:

source ~/git-completion.bash

Here all relevant code for the addition of your git status to the bash prompt:

function _set_git_envar_info {
GIT_BRANCH=""
GIT_HEAD=""
GIT_STATE=""
GIT_ROOT=""
if [[ $(which git 2> /dev/null) ]]
then
local STATUS
STATUS=$(git status 2>/dev/null)
if [[ -z $STATUS ]]
then
return
fi
ahead_pattern="# Your branch is ahead "
behind_pattern="# Your branch is behind "
GIT_BRANCH="$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')"
GIT_HEAD=":$(git show --quiet --pretty=format:%h 2> /dev/null)"
GIT_ROOT=./$(git rev-parse --show-cdup)
GIT_STATUS=""
if [[ ${STATUS} =~ ${ahead_pattern} ]]; then
GIT_STATUS="↑"
else if [[ ${STATUS} =~ ${behind_pattern} ]]; then
GIT_STATUS="↓"
fi
fi
if [[ "$STATUS" == *'working directory clean'* ]]
then
GIT_STATE=""
else
GIT_HEAD=$GIT_HEAD":"
GIT_STATE=""
if [[ "$STATUS" == *'Changes to be committed:'* ]]
then
GIT_STATE=$GIT_STATE'+I' # Index has files staged for commit
fi
if [[ "$STATUS" == *'Changed but not updated:'* ]]
then
GIT_STATE=$GIT_STATE"+M" # Working tree has files modified but unstaged
fi
if [[ "$STATUS" == *'Untracked files:'* ]]
then
GIT_STATE=$GIT_STATE'+U' # Working tree has untracked files
fi
GIT_STATE=$GIT_STATE''
fi
fi
}
function _git_prompt () {
_set_git_envar_info
#git name-rev HEAD 2>> /dev/null | sed 's#HEAD\ \(.*\)# (\1)#'
GIT_PROMPT=$GIT_BRANCH$GIT_HEAD$GIT_STATE
if [[ -n $GIT_PROMPT ]]
then
echo "("$GIT_PROMPT") $GIT_STATUS"
fi
}

You may use the _git_prompt function to generate the git status information and display it in your bash prompt like in the following example:

ORANGE='\[\e[0;33m\]'
DGREEN='\[\e[0;32m\]'
RED='\[\e[1;31m\]'
NORMAL='\[\e[0m\]'
#Prompt:
export PS1="$ORANGE\t@\h $DGREEN[\w]$RED \$(_git_prompt)$NORMAL\n"

Now you have a prompt like this in a GIT repository:

14:11:13@computer [~/Repositories/repo-pub] (testbranch:eae62d0)

Special thanks to hehejo for some bash code and to http://www.codethatmatters.com/2010/01/git-autocomplete-in-mac-os-x/ for a solution to the autocompletion issue. If you are interested in project management, here is a very interesting article about a successful git branching model.