Quick Subversion Find/Grep Trick

| No Comments | No TrackBacks

One of the most annoying features of CVS and Subversion (but especially Subversion) is the extra directories they create in your working copy of a repository. In the case of CVS, this is nearly tolerable because the directory is named "CVS" and generally only contains three files each. Irritating, but not terrible. The Subversion system creates directories named ".svn", but includes a half-dozen files it uses plus an unmolested copy of each file.

The annoyance comes in when I execute my favorite commands find and grep -r. For the Unix-uninitiated, find searches the current directory and all subdirectories for files according to some criteria (generally based on file names, file owners, dates, or file permissions). The grep command performs a textual search for some string of text (actually a regex, but we'll leave that out of it for now). Add the grep -r command and you have a version that also searches all subdirectories for files as well.

When programming, I use these commands frequently for common tasks. For example, occassionally I'll name a method something and then change the name later. This generally requires that I find every place in my code I used that method and rename the calls. Let's say I renamed "foo()" to "foobar()":

grep -r "->foo(" lib

Now, I can find each file and have vim search and replace every occurence or more carefully edit the files (as sometimes I have to be careful because another method named "foo()" might need to stay as is).

There are similar scenarios when I need to use find such as trying to locate all my library files to document or whatever.

Anyway, the problem with using the above command or find is that I end up with all the matches from grep twice and all the files in find twice plus some because of the duplicates. I really would like to pretend the files in the ".svn" directories just didn't exist. Thus, I created some quick commands to do just this in my shell today.

Initially, I did the quickest and dirtiest thing and added the following to my bash resource file (".bashrc"), which is read whenever I startup a terminal:

sfind() { find . -name .svn -prune -o "$@" -print; }
sgrep() { grep "$@" | grep -v "/\.svn/"; }

These work pretty well. Now I can run "sfind" with all the regular "find" arguments and get it working on the current directory or "sgrep" with all the regular arguments and get it working. However, these will (for most queries) not return the results from ".svn".

However, sfind isn't quite as nifty as I'd like because it would be nice to be able to use a directory as the first argument to specify a different directory to search. I prefer the Linux-style find that doesn't require the first argument (i.e. it will use "." (current directory) as the directory if no directory is given), which will also give me the Linux-like functionality when I'm on my Mac or another system that doesn't implement it. I augmented my first revision of "sfind" as follows:

sfind() {
   if [ -e $1 ]; then DIR=$1; shift; else DIR="."; fi
   find "$DIR" -name .svn -prune -o "$@" -print
}

Now, I can use a directory as the first argument or not. If not, then it uses the current directory as the default. This, of course, would fall apart if I had a directory named the same as some option I might use ("-name", for example). However, naming directories starting with dashes isn't something I think I've ever done, so I'm not too worried.

Hope this is interesting to y'all. Cheers.

No TrackBacks

TrackBack URL: http://contentment.org/mt/mt-tb.cgi/487

Leave a comment

About this Entry

This page contains a single entry by Andrew Sterling Hanenkamp published on July 8, 2005 7:41 AM.

Some Agent/AI definitions was the previous entry in this blog.

The Internet is making the world a "bigger" place is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.