Friday, March 26, 2010

Distributed Version Control

I've been using Mercurial for the past couple of weeks: I'm working on the sort of small, “skunkworks” project that doesn't belong in the company's main version control system. Normally I'd create my own Subversion repository to hold it. In this case, I thought my coworkers might want to run and modify it (which they did), so distributed version control (DVCS) seemed like a good idea. I picked Mercurial primarily because Git confused me when I tried it. Mercurial has a simple interface, with many of the same commands used by Subversion, and the built-in web-server is nice for distributing changes.

Before continuing, I should say that I'm a Luddite when it comes to version control. It's not that I don't like using a VCS — indeed, I think that any team or project that doesn't use some form of version control is on a short road to unhappiness. But I'm not one to jump to the newest and shiniest VCS. I was using SCCS until long after CVS became available (working directories? we don't need no stinkin' working directories!), and it wasn't until this year that I converted the last of my personal CVS repositories to Subversion (I kept forgetting which commands went with which projects).

So I'm naturally reluctant to jump on the DVCS bandwagon. But more than that, I don't see a clear use case for a typical corporate development team.

There are definitely some situations where DVCS is appropriate: my skunkworks project is one. Linux development is another. But the reason that DVCS is appropriate in these situations is because everyone's off doing their own thing. In the case of Linux development, you have thousands (?) of individual developers making little tweaks; if those tweaks are perceived as a Good Thing, they'll eventually make their way into the (central) repository owned by Linus. On the other hand, you have dozens of distributions, all pulling from that repository and adding their own pieces. Coordination is ad hoc; development is largely (to borrow a phrase) a Team of One.

In a corporate environment, however, you don't often have people doing their own thing (unless you have a very dysfunctional team). Instead, everyone is working on (possibly overlapping) pieces of a common codebase. To me, this implies that you want one “authoritative” copy of that codebase: you don't want to guess who has the “best” copy on any given day. And once you admit the need for some level of centralization, the checkin-merge-push cycle demanded by a distributed VCS seems like a lot of effort compared to the update-checkin cycle of a centralized VCS.

“But I can work on a plane!” I've actually heard that argument. At the time, my response was “I didn't think you traveled that often.” But a better response is “why do we care about your commits?” And that's the main point of this post.

“Check-in early, check-in often” is a great motto to live by. Especially early in a project, when you're experimenting. It's nice to be able to roll back to what you were doing an hour ago, or roll forward some pieces you thought you didn't need but now realize you do. If you use continuous integration, you'll check in at least daily.

However, frequent checkins create a quandary: once your time horizon moves past a few hours, you don't want all those commit messages in your repository! Think about the last time that you looked at a repository log: why did you do it? Probably to find when and why a particular file changed; maybe several changes, widely spaced in time. I've done that a lot, and stumbling over dozens of minor checkins (even after using annotate) is a royal pain.

One way to work around this issue (when it's even considered an issue) is to use “feature branches”: all new development takes place on a branch, and then gets merged back to the trunk when completed. This is the way that I learned how to do multi-person source management some 15 years ago, using ClearCase. Unfortunately, many teams are scared by feature branches, or perhaps they're scared of the merge at the end, so they stick with the “CVS” approach of doing all development on the trunk, with branches confined to bugfix duty. And at the other extreme, standard DVCS procedure is that the repository is the branch — in other words, once you've pushed, your trunk has a bunch of undifferentiated revisions.

My alternative is something I call “ghetto DVCS”: cloning a central repository, and working in the clone. When you're done, you copy your changes into a working directory, and check them into the “real” repository. Ironically, I started doing this while I was traveling, and wanted to use source control without access to the central repository. I decided that I liked it enough to continue even when I had wasn't traveling. For example, Practical XML revision 87 represents close to two weeks worth of work, during which I added, deleted, or renamed files many times. If I had been working directly in the central repository, there would be a dozen or more revisions.

The problem with my approach is that it can be a lot of work, particularly if you rename existing files. And this is where I think DVCS offers promise: since they track the ultimate parent revision for each file in your local repository, they could easily merge the tip with this parent and ignore the interim revisions (and maybe Git can do this; as I said, it confused me, but tip merges make a lot of sense for the Linux development model).

Until that happens, I'm sticking with svn.


Update: my friend Jason pointed out that git pull has a --squash option. Which makes a lot of sense, given the pull-based nature of the Linux development model. It's not the "push tip" that I want, but is closer. Now I just have to figure out how to use the rest of git.

Monday, February 22, 2010

Problems and Opportunities

There's no such thing as problems, only opportunities

There may be people and situations for which this is true: tow-truck operators and plumbers come to mind. But for the rest of us, it's critically important to tell the difference — in fact, that is the difference: criticality. Opportunities are optional, problems aren't.

I'm not sure where the “no problems” slogan came from, but I suspect a half-asleep MBA student in ECON 101. In economics, there truly are no problems, nor opportunities either, only choices. But every choice has an “opportunity cost,” which, confusingly, is the net profit from the best alternative. If you (like many business students) don't think of the possibility that net profit can be negative, it's an easy step from cost to slogan.

Houston, we have an opportunity

In the real world, however, net profit can be negative. And when you're a quarter million miles from earth, with limited oxygen and electricity, the opportunity cost of the wrong choice is death. In the computer industry, we're not likely to face such drastic costs; but that doesn't mean we don't have problems.

Wednesday, February 17, 2010

JavaFx: What Niche does it Fill?

I've had fun playing around with JavaFx. I can't shake the feeling that it's in the same situation as Java was in 1996: targeted to a specific niche, but much more useful as a general-purpose language. Unfortunately, everything I've seen says that Sun (Oracle) intends to keep JavaFx in the RIA niche, a competitor to Flash and Silverlight.

And if that's their plan, here's my response: ain't gonna happen. Flash got to its position of ubiquity not so much because of technical merit, but because Adobe has mindshare among the graphical designers who are — like it or not — the arbiters of what goes on the web. At best, these people think of Java as “something to do with JSPs”; at worst, they think of applets (or more likely, negative folklore about applets, because they've never actually seen one). JavaFx is as likely to replace Flash as The Gimp is to replace Photoshop.

More important, Flash itself may not have much longer to run: there seems to be a strong backlash against plugins. Apple, with the iPhone and iPad, is the leading edge of this movement. However, the same attitude is showing up in desktop browsers, as you can see from the many pages describing how to make Java work with Chrome (I spent a half hour trying to get the latest Sun JRE to work with Chrome on Linux, but eventually gave up; call this statement sour grapes if you wish).

Instead, I think RIAs will be built with HTML (5) and JavaScript. This is, again, something very familiar to web designers. Most seem to go the route of raw HTML plus a library such as JQuery, but libraries the Google Web Toolkit and Yahoo UI will probably be more useful to the application (versus web) developer.

But, what about the mobile market? After all, the JavaFx tagline is “all the screens of your life,” and they've certainly made an effort to create one platform to span desktop and mobile applications. However, as you dig a bit deeper, you find that mobile device support is not quite ready for prime time: “Sun is working with Mobile Device Manufacturers and Mobile Operators to enable out of the box support for JavaFX.” What of the billions of Java-enabled handsets already out there? It appears that they're out of luck (although I haven't actually tried running a JavaFx app on, say, a Motorola RAZR). And, just in case you missed it, JavaFx will never find its way to the millions of iPhone users.

To wrap up: I believe JavaFx has a bleak future if it's confined to the RIA and/or mobile markets. But those aren't the only markets out there, and there's no reason that JavaFx has to remain confined. As I wrote when I started this blog, I like Java because it has a simple yet very powerful mental model, and the JavaFx language seems to have the same characteristics. It encourages a functional style of programming while still being object-oriented. There are, of course, other languages that do the same thing; Scala, for example. But those other languages don't have the Oracle marketing department behind them.

There's a lot of discussion about how Java is to evolve. But language evolution is a tricky thing. I could easily do without the mess that is auto-boxing; other people feel the same way about generics. And C has remained essentially unevolved since the 1970s, yet is still very useful (albeit in limited niches).

So I'll end with a question: will Java continue to acquire cruft, or is JavaFx the future?