WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.
As should be obvious from my recurring blog topic of
coding style, I care a lot about
code readability and style.
One criticism I've heard frequently is that you shouldn't reformat code to be style-compliant, since that
introduces lots of diffs into the version history of a file. Oh no, diffs! What horror! Think of the children! Somebody, The children!
I have two responses to that line of thinking:
- First, you clearly don't agree with me on the importance of consistent formatting and readability. Perhaps
I should just grow up, but when I see code like this I cringe:
void myfunc(int a_foo, int a_bar)
foo = a_foo;
Source formatting typically doesn't rename variables (to wipe out the underscores ( _ ) from variable names) but
it certainly could put the opening brace back up where it belongs, as well as remove the space between the method name and the opening parenthesis, etc.
Reading the above code is the common operation. Tracking down line history is the occasional operation.
Second, and this is the more important point: You're probably not familiar with, or at least well versed in,
source code archaeology.
Source code archaeology is very similar to the archaeology you're familiar with: you dig down, layer after layer, uncovering artifacts from a particular time period. You essentially get to see the state of affairs at one particular point in time. Then historical events occur and layers upon layers are deposited on top.
With source code archaeology, you can dig back into the history of a file. Let's pretend we agreed on a particular coding style for the NetBeans source code base, and I went and ran a filter over the entire code base, reformatted it, and checked the code in with the comment "
Source code reformatted to spec using codestyle ide/formatsettings.xml". Reformatting the entire source base (yes, I know, blasphemy!) is usually criticized as bad because you can't find out why a particular line was added or changed, since now the version information for the line points to the reformatting delta. But but but - remember the layers! (Insert mandatory Shrek reference here...) It's easy to go to the layer below the reformat, and see what the version of the file looked like prior to the reformatting delta. So, once you've done a giant reformat of the source base, looking for the origin of a particular source file line may involve multiple operations. First you determine what delta corresponds to the current version of the line. If you see that it was for a reformat, you peek at the version below it, locate the same line, and look at its original comment.
Now, you might argue that that's an extra step. You would be right - but think about it, what's more common, reading code, or reading the checkin comment for a particular source line? As long as you can get the team to use the same source formatting conventions (perhaps even performed or enforced automatically at checkin) you'll only need to do this global operation once.
Tools should make this job easy. It's not all that hard on the command line either. You may have heard of the "cvs blame" command.
tor:1% cvs blame
Unknown command: `blame'
CVS commands are:
add Add a new file/directory to the repository
Ok, so that's not really the command, but it's the common name for the cvs annotate method! It lets you figure out who to blame for the ridiculously stupid bug you just found in the code. The real name is cvs annotate.
With cvs annotate you can get annotations for the current version. Let's say that you discovered that a reformat happened in revision 1.43 of file Foo.java. To see what the file looked like before that, simply do
tor:2% cvs annotate -r 1.42 Foo.java
1.1 (tor 24-Mar-03): /*
1.1 (tor 24-Mar-03): * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
1.1 (tor 24-Mar-03): * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
1.1 (tor 24-Mar-03): */
1.1 (tor 24-Mar-03):
1.1 (tor 24-Mar-03): package foo.bar;
1.1 (tor 24-Mar-03):
1.1 (tor 24-Mar-03): import java.awt.geom.Rectangle2D;
As I mentioned, tools should make this easy. I'm not sure what the current state of this is in NetBeans' new CVS support, or in other IDEs. I had a strong need for this back when I worked with SCCS and Teamware on Sun's C++ development environment. I built a prototype for doing this kind of exploration; I think it's still relevant today, seven years later, so I'll include a couple of screenshots of it. Consider this a wishlist for $favorite_ide, in my case NetBeans.
The idea is that you get to open your source file in a version-annotated view, where all the source lines are colored according to some source code metrics. For example, really old lines have a dark background, and recent lines have a bright red background. (To show which lines belong to the same delta, look for the < and > signs in the left margin showing contiguous blocks, since code about the same age can have roughly the same color but should be logically distinguishable.
The point is that you want to be able to click on a line to be able to see its checkin comment - and to quickly cycle through previous versions of the file (and diff between versions).
Another possible coloration assigns a different color to each user who has touched the file. The overview gives you an indication of who's most responsible for this source file.
There are some other minor things here too, but I think I've made my point: Source Code Archaeology - it's important. It needs better tools support. But it's possible today, and should help you make the transition to a properly formatted source code base.