Current Git Branch in Bash Prompt
April 12, 2008Earlier today, my roommate and I were enjoying our afternoon watching the TextMate for Rails 2 Peepcode and I noticed that in the bash prompt, the current branch was shown in parenthesis. I thought this was a wonderful idea and thought I'd add it to my own bash prompt.
Update: Some much better alternative methods have been posted in the comments, please take a look below.
Here is the code to do it:
1 export PS1="\[\033[38m\]\u@\h\[\033[01;34m\] \w \[\033[31m\]\`ruby -e \"print (%x{git branch 2> /dev/null}.grep(/^\*/).first || '').gsub(/^\* (.+)$/, '(\1) ')\"\`\[\033[37m\]$\[\033[00m\] "
This will make your bash prompt look like this:
1 user@hostname currentDirectory (branch name) $
The important part of the PS1 in the first code snippet is this:
1 # this goes somewhere in your PS1 (it'll make the branch name red) 2 \[\033[31m\]\`ruby -e \"print (%x{git branch 2> /dev/null}.grep(/^\*/).first || '').gsub(/^\* (.+)$/, '(\1) ')\"\`\[\033[37m\]
I decided to try to do this with sed and not ruby. I came up with this:
1 export PS1="...\`git branch 2> /dev/null | grep -e ^* | sed -E s/^\\\\\\\\\*\ \(.+\)$/\(\\\\\\\\\1\)\ /\`\[\033[37m\]$\[\033[00m\] " 2 # no, your browser is not having rendering issues 3 # there seriously are that many backslashes
Other than the disgusting backslashes, it's pretty nice. If you use single quotes on the outside instead of double, you can lose a few backslashes:
1 export PS1='...`git branch 2> /dev/null | grep -e ^* | sed -E s/^\\\\\*\ \(.+\)$/\(\\\\\1\)\ /`\[\033[37m\]$\[\033[00m\] '
Comments
Mine:
Evgeny,
Your solution doesn't work quite the same way. git branch outputs every local branch, so your solution would list all the branches, not just the current one.
So to fix that, you can pipe git branch through grep:
Also, your solution includes the parenthesis regardless if you're in a git directory or not.
I'm sure there is a better way to do what I'm doing using sed or awk, but I'm not well-versed in either so I stuck to ruby.
Update: I took a stab at it in sed. (see bottom of post)
There is already a function to do this in the git distribution. If you check out the source there is a directory called
contribwhich has a bash completion file that gives you a __git_ps1 function.Then you can just put \$(__git_ps1) somewhere in your PS1 and get the current branch. It doesn't output anything when you're not in a git directory. It also gives you branch name and subcommand tab completion.
this ends up in my ZSH prompt, but it should work for bash too and comes with as few backslashes as possible, which makes it even readabel:
Philip
I've adapted the solution to work without any backslashes in a ZSH prompt theme environment.
Here's my take on this:
http://www.gnegg.ch/2008/04/git-branch-in-zsh-prompt/
Philip
Here is mine
I used a cut because the original solution was inclusing all branches upto the one I was working on, and one line break for each too ... the "cut version" is:
I've been doing the same thing, but I've found that
1 git name-revtends to give more detailed output when you aren't on a branch (e.g. try checking out master^). The code I use is:
I actually nabbed that code from someone else's bashrc a while ago, but I forgot to save a link and so can't give credit, unfortunately.
If you use the auto completion script that come with Git, you get the auto complete functionality plus the __git_ps1 method that Adam mentioned above. You can place the __git_ps1 method in your PS1 and get the branch name in your prompt. I've got a short tutorial on getting it working on OS X at http://blog.ericgoodwin.com/2008/4/10/auto-completion-with-git.
Eric
Well that was somewhat botched. Here it goes In ~/.bashrc
For git directories
For svn directories
Thanks for the plug!
I first learned it here:
http://acts.as.streeteasy.com/archives/2007/12/19/git_in_your_prompt/
After reading this post I switched over to the __git_ps1 method.
The relevant part being...
the 'grep | sed' part can be avoided and implemented in a single sed:
I've since added a Unicode skull and crossbones when I'm in a branch with uncommitted changes:
http://www.scrnshots.com/users/topfunky/screenshots/89842
branch, status and changed files: http://volnitsky.com/project/git-prompt
Thanks for the useful hints here, I tried to make a version that changes colour depending on the state of the git tree (green for no changes, red for uncommitted changes). I had a hard time getting the colours right, but I finally found out how to do it (I'm using the bash):
NB: the colour codes are ANSI terminal codes with a REAL escape code in ASCII value.
Just for reference, I found this page with a good description of the colours: http://ascii-table.com/ansi-escape-sequences.php
Before I set the git branch version, I first test (line 7) whether I'm in a git managed tree.
Cheers
Simon
So I've added the __git_ps1 function to my PS1 bash variable, but it only runs once (when the shell is started). Is there a way to make this refresh every time a command is run? Right now it will still say "(master)" even when I leave a repo's folder and cd to a non-git folder.
Mike,
It's only running once because it's evaluating at that time. You can stop that by either using single quotes instead of double, or using a backslash before the $.
I hope that works out for you.
@Mike: or, you can make a function, and pass this functions name to PROMPT_COMMAND variable. From this function, you can update xterm terminal title too, like:
Simon, did you resolve the command prompt line-wrap issue that arises due to the escape codes?
@Simon: I took the liberty to modify your version a bit, because the colors in your version weren't working for me. This version uses tput setaf to determine the ASCII color codes. It also does some tricks to avoid the problem with line wrapping when writing longer lines.
Tested on Mac OS X Terminal on Snow Leopard.
I use 'tput' since escape codes confuse me:
Leave a Comment