Stop the presses: bash said to embrace subversion and git
Update: I've since updated and moved this script. See my new blog post.
I had a chance to pair with Rob today. On his console window, I noticed something I wanted: his bash prompt had an indication that he was in a Git repository along with the branch he was on. Later, after he'd left, I found myself wondering how that worked and that I simply had to have it, and I wasn't willing to wait a whole day to figure out how he'd done it. Patience is not a virtue. (In that spirit, click here for the code if you're too impatient to read the rest of this blog entry which I spent countless hours writing. Uphill both ways. In the snow.)
A few minutes of googling turned up a blog entry with relevant bash fu. The code there was for changing the prompt such that it indicated whether you were using svn, git, svk or Mercurial along with some repository metadata. A couple of minutes later (it took a while to copy and paste the code since it was interweaved with comments), I found out it didn't work on Leopard. readlink turned out to be the culprit. Instead of figuring out why it wasn't working, I replaced it with something simpler (specifically I used: base_dir=`cd $base_dir; pwd`). Voila, things worked: I now had a hella cool prompt that showed me if I was in a Subversion or a Git repository - I never used Mercurial, and left SVK for Git a couple of months ago. Yay.
Being who I am I had to do something more with this new ability to distinguish between Subversion and Git. And I knew exactly which itch to scratch: 90% of the time I use the same scm commands. I even had shell aliases for them so I wouldn't have to type them. A few minutes later I'd converted my previously Subversion specific aliases to generic ones that worked with Git too. Screenshot says it all:
If you want the same, download the script as ~/.bash_vcs and add source ~/.bash_vcs at the end of your ~/.bash_profile.

6 comments:
One thing that I have noticed is that I have lost the colour in the bash prompt.
Nevermind. I realised it was due to an incorrect bold setting.
One thing I did not agree with in your script is commit automatically having the -a flag. I personally have removed it for my taste.
Pretty cool!
One edge case I've run into is that SVN doesn't work properly when the directory you're in is a symlink.
In other words I have my svn tree directory somewhere on the filesystem and I make a symbolic link to it. Then I cd into that symbolic link.
In the following example symlink_to_dir is a symbolic link located in /Users/grant/parent_dir that points to an svn tree somewhere else on the filesystem.
grant:~/code$ cd symlink_to_dir
svn: '/Users/grant/parent_dir' is not a working copy
svn: Can't open file '/Users/grant/parent_dir/.svn/entries': No such file or directory
grant:(svn)symlink_to_dir[]/$
Not really expecting you to fix this edge case, but if you know an easy solution please share it. Thanks!
@Grant Hutchins
The solution is actually pretty simple. Not sure why, but the author chose to trace up directories until the root of the repository is found, which is completely unnecessary. The first 6 lines of svn_dir() can be replaced with the following 3 lines:
[ -d ".svn" ] || return 1
ref=$(svn info | awk '/^Revision/ { sub("[^0-9]*","",$0); print "r"$0 }')
sub_dir="/"$(basename `pwd`)
$base_dir was only used as a argument for `svn info`, but when you give it no arguments it defaults to the current directory, and since we've already established that there's a .svn/ directory, svn info will work fine. I'm not convinced that $sub_dir is useful, but I left it in for consistency with the other functions.
Hope that helps, even if it is 10 months later. :-)
@Grant Hutchins (et al)
There is a simple way to get around the symbolic link issue with Subversion. It's actually unnecessary to use a while loop to ascend up to parent directories, or to use awk to parse output from `svn info`. Replace svn_dir() with the following:
svn_dir()
[ -d ".svn" ] || return 1
ref=`svnversion`
vcs="svn"
alias pull="svn up"
alias commit="svn commit"
alias push="svn ci"
alias revert="svn revert"
}
The svnversion command returns the revision of the current directory in the working copy, and handles mixed revisions (e.g. 322:324M) so you can actually see a bit more useful information in the prompt. This is especially true when subtrees of a working copy may not always be updated in sync, and you can actually see what may be out-of-date more easily.
Muness, thanks for the post! I had never thought of doing this, and it has definitely boosted my productivity. :-)
Quinn,
I didn't explain base_dir sufficiently. I want it to be the name of the top-most svn directory. I use it as the project's name (in the prompt and in the tab title). The current svn_dir implementation does cause problems with symlinked directories, but I use svn so rarely that isn't an issue for me.
Thanks for simplifying the svn version number generation. :)
Muness
Post a Comment