Adventures in version control

So I spent a lot of the weekend refactoring my Healthy Homes database system. (I know, what a party animal.) And after getting some solid work checked in, I realized it was definitely time to do a major refactoring of the Data Access Layer (DAL) code.

See, my original system had been developed around… I am not making this up… a Microsoft Access MDB file. Which worked great! But all my database code worked with System.Data.OleDb* objects. In many places, calling code had public access to things like OleDbConnection and OleDbCommand objects. In other words, not very well abstracted, right?

Meanwhile, rather predictably someone is asking for the same application, but with a Microsoft SQL Server back end. And someone else is asking for the same application with some kind of Web Services back end. Both reasonable requests! Neither one so compatible with all those OleDb* objects.

Time to break the calling code’s dependency on everything OleDb* related, right? Dang, that turned out to be a couple solid days of refactoring. And my unit tests aren’t up to the challenge, so there will be a ton of manual testing. At this moment, the modified code is about forty errors away from building.

Now here’s the thing. The original client, the one who for now is still using the Access back end, is doing acceptance testing on the pre-refactored system. And they might legitimately find a defect or, more likely, something they want to change. And I don’t trust the mega-refactoring yet. Now what?

Easy! Since I’m on the 2.0 branch now, I created a new branch off it called 2.0-fixes. It won’t contain the refactored code because I haven’t checked that in yet. And create another branch called 2.1-dal-refactoring for the current work. I used the “switch workspace” command in Subversion to get onto that latter branch and it’s all good.

When I hear back from the original client with any defects or change requests, fine, I can go do those on the 2.0-fixes branch, and merge them into 2.1 later on.

Why this matters

In this application, it’s just me. But I did a smaller project recently in which the one Rails developer was waiting for the results of the CEO/salesperson’s big presentation to a potential bombshell new client. “You have to hold off on the changes for the Frock Nozzle feature,” said the CEO, “because we can’t have them half-working for our demo with Megacorp.” The Rails developer, fairly fresh to commercial project development, complied. Neither one of them was aware of the ability to shunt the Frock Nozzle feature onto its own branch to be merged in later.

The problem with doing all your development on a single trunk is exactly this: You have to time your major features to fit between external events! Think about it. If Jen the Rails developer can’t start on the big feature while a big demo is pending, and she has to finish it before the next conference presentation or sales meeting, that logically means any feature has to fit between those two events or it will never get done. It’s a recipe for stagnation, technical debt, and failure.

Thus you either have to space out your dog-and-pony shows, or you can’t do any large-scale feature development. In short, you’re single-tracked.

So off we go

Today I’m able to work on the big-picture issue of hard dependencies on OleDb* classes and also prepare to adapt to change on the current release. Life is good.