Wednesday, June 28, 2006

Fixing Subversion with Command Line Judo

As many of you know, David Bock and I are writing a book about programmer productivity, which includes a fair amount of command line judo. Here's a little piece that I developed for my project.

Occasionally, Subversion breaks with an error that references a path that includes /!svn/ and another line that talks about status 200. (Sorry, I don't have an exact replica right now because it's fixed. I’ll try to capture one in the wild next time I find one.) This seems to happen when someone checks in a binary that is being used by another application: Word document, Excel spreadsheet, or PDB file.

When this happens, you must go through your directory structure to identify the bad file. This is cumbersome (more in a second about this). Once you have found the bad file, remove it from the repository view (i.e., remove it directly from the repository, not your local file system) and do an update. To find the file, you must go to every directory in your local copy of the repository and do an update in that directory. The first directory whose update breaks holds the problem file, which you must find by trial and error. You can do this with Tortoise, but it takes forever.

If you have the foresight to have Cygwin (and therefore the Bash shell) on your machine, you can issue this command (in Bash) from the root directory of your repository:

find . -type d | grep -v "/.svn" | xargs svn up

This command finds every directory, eliminates the ".svn" folders, and pumps the directory name into "svn up". The first directory that breaks when this command executes is your problem folder. Problem solved.

My educated guess on our repository is that it would take 20 minutes to use Tortoise to update every folder, one at a time. It took me about 10 minutes to develop this little bit of command line judo. So, in this case, automating the solution actually took less time than the brute force approach. But, even if the automated approach takes longer to develop, you have a tool for the next time it happens.

Stay tuned for a bunch more stuff like this when we get The Productive Programmer done!

Wednesday, June 21, 2006

Cheeburger, Cheeburger, cheeps, pepksi

One of my coworkers doesn't have a blog, but he successfully identified another sacred cow that we're converting to cheeburgers on our project. Yet, he's so altruistic, he won't take credit for the idea, saying that it's Marjorie's idea instead. So that he can remain anonymous, I'll just call him Zak T. No, that's too obvious, let's call him Z Tamsen instead.

Zak's sacred cow is the convention in the .NET world of using Pascal casing for namespaces, which is a terrible idea. We've already run into situations where a namespace clashes with a class name, which is annoying. So, we've decided to make all our namespaces all lower case, ala Java, with underscores to separate logical names (very un-ala Java).

Namespaces in .NET are particularly broken, and not just the capitalization convention. This is one of the things that Java got really right, but in a very subtle way. One of the early annoyances for most Java developers is learning the concept of a root directory, and how the package names of your code must match up to the directory structure. Once you grok that concept, though, it makes perfect sense. Only much later do you figure out that this is one of the subtle elegances of the Java language. Because the package structure is tied to the underlying directory structure, it is difficult to create class names that overlap because the OS won't let you create 2 classes by the same name in the same directory. Score one for Java, leveraging the OS to prevent headaches for developers. Of course, with the advent of virtual directory structures in JAR files, you can now create conflicts, but it is thankfully still rare.

Namespaces in .NET have no such useful restrictions. It is trivially easy to create name conflicts because the namespace is just an arbitrary string. Most of the .NET developers I know (especially if they've done any Java) use the useful "namespace must match directory structure" convention (with less restrictions on the actual root folder). In fact, one of my colleagues, Yasser, has created a very useful utility called Namespacer that verifies that your .NET class' namespace matches the directory structure. After some use on our project, he's planning to open source it. Short of fixing namespaces in .NET, at least there is a way to verify the adherence to a useful convention.

Sunday, June 18, 2006

Being Productive in Cincinnati

I'm speaking at the Cincinnati Java User's Group (CINJUG) on Monday, June 19th. I'll be presenting my talk The Productive Programmer, based on the book upon which David Bock and I are diligently but slowly working. This has become a pretty popular talk with both user groups and at No Fluff, Just Stuff shows, and I keep finding more stuff to cram into it. Soon, I'm going to have to start pruning the tips or convert it into a Part 1, Part 2 affair. If you are in Cincy, stop in and say "Hi".