Since I”ve read much about git and how great it is, I recently thought that I had to try it myself. And indeed, it is quite amazing and is nice to work with. There was one thing that I disliked, though: I never quite knew in which branch of my repository I was, especially after I”ve been away from coding for a few hours.
Of course I could just look that up, but I tend to forget that and then end up with code that belongs to a different branch. Now the shell prompt looked like a good place to show the current branch, but simply executing “git branch | grep ^*” would only work in the top-level directory of the repository. So I wrote the following function which will traverse all containing directories and look for a .git directory. Having found one, it will nicely print the the branch in dark green color, with a @ sign in front of it:
Update: As many people have pointed out, bash-completion provides a function called __git_ps1 which will happily print the current git branch and can be used as well. I don”t quite like the rest of bash-completion, though, so I”ll stick with my own.
As Yuri pointed out, git branch works from any directory, so here”s the updated (and much shorter ๐ ) version:
function formattedGitBranch { _branch="$(git branch 2>/dev/null | sed -e "/^\s/d" -e "s/^\*\s//")" test -n "$_branch" && echo -e " @\e[0;32m $_branch" }
Having this in my .bashrc, I could integrate it quite nicely with my prompt:
\[\e[1;32m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\]$(formattedGitBranch) \[\e[1;32m\]\$ \[\e[m\]\[\e[0m\]
Screenshot:
the git bash-completion scripts come with a prebuilt (and more fully-featured) way to do this. It””ll even show you if you””re in the middle of a rebase, etc. Do a google search for __git_ps1
git branch works from any directory inside git work tree.
Another solution:
if [[ `git rev-parse –is-inside-work-tree 2>/dev/null` == “true” ]]; then
git branch | grep ””^*”” | sed -e ””s/*/@/””
fi
Better use:
git branch –no-color 2>/dev/null | sed ””-nes/^*[[:space:]]*//p””
git branch โno-color 2>/dev/null | sed ””-nes/^*[[:space:]]*//p””
If you have the git bash-completion scripts installed, take a look at the $__git_ps1 function. Yours is pretty simple and clean ๐
Git already has a number of such small helpers. All this scripts starts with a __git prefix. One of them is __git_ps1 which meets approximately the same purpose as your formattedGitBranch.
You can get this, and a lot more, when using Zsh and the vcs_info plugin.
If you have Git””s Bash-completion installed (and enabled), you can get away MUCH more easily, since it already provides a “__git_ps1″ function. Here””s a snippet from my .bashrc:
# Show Git branch in bash prompt
export GIT_PS1_SHOWDIRTYSTATE=1
export PS1=””[33[01;32m]u@h[33[00m] [33[01;34m]w[33[00m]$(__git_ps1 ” [33[01;33m](%s)[33[00m]”) $ ””
In any case, even if you don””t have Git””s Bash-completion, your formattedGitBranch() function is not efficient. A much more efficient way to determine your current branch name is simply:
git rev-parse –symbolic –abbrev-ref $(git symbolic-ref HEAD 2> /dev/null)
Have fun! ๐
…Johan
Git already has that functionality somewhat included. Here””s a snippet from my .bashrc for having the git or svn branch in the prompt (note also that the git-completion.bash will give you bash completion of git branches and other goodies):
GIT_VERSION=`rpm -q –qf “%{VERSION}” git`
. /usr/share/doc/git-“$GIT_VERSION”/contrib/completion/git-completion.bash
parse_svn_url() {
svn info 2>/dev/null | grep -e ””^URL*”” | sed -e ””s#^URL: *(.*)#1#g ””
}
parse_svn_repository_root() {
svn info 2>/dev/null | grep -e ””^Repository Root:*”” | sed -e ””s#^Repository Root: *(.*)#1/#g ””
}
parse_svn_branch() {
parse_svn_url | sed -e ””s#^”””$(parse_svn_repository_root)”””##g”” | awk -F / ””{print ” svn:” $0}””
}
PS1=””[u@h W[33[01;32m]$(__git_ps1 ” git:%s”)$(parse_svn_branch)[33[00m]]$ ””
hmm… strange… replace all the double-double quotes with single quotes in the above…
I have the following in my .bashrc. It””s the same as yours, but with an additional smily ๐ if the return code of the last app was 0, and a smily ๐ if it was !=0 ๐
# git branching
function formattedGitBranch {
checkDir=”$PWD”
# check whether we””””re in a git repository
while [[ “$checkDir” != “/” ]]; do
if [[ -d “$checkDir/.git” ]]; then
GIT_DIR=$(cd “$checkDir/.git”; git branch | grep “^*” | sed -e “s/^*//”)
echo -n -e “@e[0;32m$GIT_DIR ”
return 0
fi
checkDir=$(readlink -f “$checkDir/..”)
done
return 1
}
# use a fancy prompt ๐
PS1=”[33[01;32m]u@h[33[00m]:[33[01;34m]w[33[00m]”
PS1=”$PS1 `if [ $? = 0 ]; then formattedGitBranch; echo -e ””[33[01;32m]:)””;”
PS1=”$PS1 else formattedGitBranch; echo -e ””[33[01;31m]:(””; fi`[33[00m] $ ”
export PS1
If you use bash_completion scripts
do this
. /etc/bash_completion
export PS1=””u@h:w $(__git_ps1 “(%s)”)n$ ””
Have fun
I use zsh, because of the _really_ nice completion features and this is possible in zsh too.
If you want to try it out, I””m using the .zshrc from http://grml.org/zsh/ which does some really neat things
You might also be interested in http://vc.gerg.ca/hg/vcprompt/. Which is a small program that prints formatted branch and revision info for CVS. SVN, Git and Mecurial suitable for inclusion in a shell prompt.
a “” is missing in front of the call of the function in the prompt. Should be …$(formattedGitBranch)…
I meant a backslash was missing, but thoose caracters seem to be “swallowed” when printed in the comments.