Friday, November 20, 2009

Revisionist History


Remember the Subversion 1.0 celebration T-shirts? Alas, there are no `svnadmin dump' and `svnadmin load' for cottonware.
As you might have read elsewhere, the Subversion project has recently been accepted in the Apache Software Foundation's Incubator. As part of the process, we'll be migrating all kinds of goodies off of Tigris.org — which has been the project's home (and a good one at that) for the past near-decade — and onto Apache-hosted servers. Last weekend we took the first of those steps by migrating our version control history. I managed the Subversion side of this migration, prepping the data for delivery into the ASF Infrastructure team's able hands.

But I wanted to do more than simply move our Subversion history from one place to another. See, when Subversion began, it was a bunch of source code living in a CVS repository. When the source code compiled into something trustworthy, we let Subversion hold it own source code. (For the record, we were never given cause to regret that decision.) But at the time we made that change, there was no reliable and simple way to convert CVS history into Subversion history like there is with cvs2svn today. So we just exported the latest snapshot of our main development line, imported that into Subversion, and dealt with the severed history. However, this repository migration — which was going to be disruptive anyway — presented an opportunity to stitch together our old CVS history and our Subversion history. So I did. Here's how:

  1. Using cvs2svn, I converted all CVS history to Subversion and deposited it into a temporary repository, svn-from-cvs.
  2. Now, the CVS repository data contained some trailing changes that were created after the switch to Subversion back in 2001. Most of those were commits to www/ (which we manually mirrored for a while based on our Subversion commits to trunk/www/). A couple of them were things like system-wide automated tweaks to www/robots.txt made by CollabNet folk. Also, we had real tags and branches in our CVS repos that we didn't bring with us into Subversion. So I dumped the first 3654 revisions from svn-from-cvs — the pre-switchover changes only — and loaded that into the stitch repository, svn-complete.
  3. To historically preserve the fact that apparently we didn't care too much about those old CVS tags and branches, I committed their deletion from svn-complete (but left the branches/ and tags/ top-level directories themselves).
  4. Since the first revision of our project's Subversion history (in the main svn repository) was a massive import into trunk, that would have clashed mightily being loaded atop already-existing files and directories in svn-complete. So instead checked I out svn-complete/trunk@HEAD, then exported svn/trunk@1 atop it. The local mods were the small delta between what we got outta CVS on August 31, 2001, and what we put into Subversion. They were mostly the result of $Date$ keyword formatting differences. I committed those local mods, which now brought svn-complete into sync with svn@1' except that svn-complete still had empty tags/ and branches/ directories (which were added in r532 and r1237, respectively).
  5. I dumped -r2:531 of svn, loading the result into svn-complete.
  6. I skipped r532 (the revision in which we created our tags/ directory) from svn, instead adding a no-op placeholder revision to svn-complete.
  7. I then dumped -r533:1236 of svn, loading the result into svn-complete.
  8. Once again, I skipped r1237 (the revision in which we created our branches/ directory) from svn, instead adding another no-op placeholder revision to svn-complete.
  9. Finally, I dumped the rest of the svn history (r1238:r40515), loading those revisions into svn-complete.

The result was a single repository (svn-complete) of 44170 revisions (3364 from CVS, 40515 from Subversion, and 1 cleanup revision) that contained all of the Subversion project's version control history, starting with the inception of the project. It's this data that I handed off to the ASF Infrastructure team.

The ASF Infrastructure team took this repository's data and loaded it into the ASF repository (with external commits disabled to prevent interleaved commit history). At the time that this history was loaded into the ASF repository, that repository already had 836419 revisions in it. The next 3655 revisions represent the Subversion CVS history (plus a fixup revision). This means that any historical references found in Subversion's source code, issue trackers, mailing lists, etc. that refer to pre-migration revisions (which are easy to spot, as they are all quite a bit smaller than 800000!) may be found in the ASF repository by adding 836419 + 3655 = 840074 to the revision number.

We as a project are still really finding all the places that this change of address (and revision numbers) will affect us. I can assure you that the last place I expected it to hit was my clothes closet, though!

Friday, November 13, 2009

Name-dropping Jesus

Don't you just love it when you personally benefit just by knowing someone else? Maybe (just maybe) you're considering an order of some trophies for your eldest son's soccer team, and one of the other dads on your youngest son's soccer teams says, "Oh, you should check out Awards Express — I always get my stuff from them. They turn around high-quality orders quickly and professionally. Tell 'em Tray sent you!" And instantly, you feel like some kind of V.I.P., empowered to trade on someone else's good name and reap the benefits of their relationships with a mutual contact.

That's kinda the way prayer works for Christians. I was thinking tonight about how I was taught that prayers are supposed to end. You know, some variation of "In Jesus name, Amen." This isn't merely the result of some ancient meaningless ritual passed down through the generations. It's the way Jesus told us to pray. In John 14:12-14, He tells us that after He returns to His Father (which, if you haven't noticed, He already did), He will do whatever we ask in His name. We find similar statements in John 15:16 and later again in John 16:23-26. Basically, Jesus is hearing our complaints and concerns and needs and desires, and He tells us, "Hey, I know exactly who you should talk to about this stuff. My Father is the best in the business. He can hook you up. Tell him I sent you."

Now, if ever there was a name worth dropping, the Son of God's is the one. But sometimes I wonder if the following happens when I pray:

[Tinkling sounds of bells rapping against the closing door.]

God: Yes, can I help you?

Me: Uh, yeah. I'm looking for solutions to some of Life's problems.

God: Oh, well then you've come to exactly the right spot. I designed Life — nobody knows how it works better than I do. Now, I could take a small bit of offense that you would claim the product is flawed. I can assure you that it isn't. But as it turns out, I'm also really good at forgiving, so let's just move past that. What did you have in mind.

Me: Well, I was kinda thinking that maybe you could cause X to happen. That would really work out well for me.

God [clearly uncomfortable]: Hrm. Well, that's not really how I had things planned for you, but...

Me: Yeah, I know. See, something tells me that there's a purpose for my life that's bigger than just me, but I really, really want to just get X. I just think that makes the most sense for me.

God: You seem pretty confident about this request. Are you sure you've come to the right spot? I'm usually pretty picky about making sure that the work I do is for everyone's benefit.

Me: Oh, yeah, I'm sure. Your Son sent me; told me you were the best in the business.

God: Oh! You know my Son?! Well that changes everything. You two are close? Good friends? Maybe you guys work together?

Me: [clearly uncomfortable] Well ... I wouldn't exactly say we're close, really. I met Him some years ago, and we see each other from time to time. He's good friends with my wife's grandparents, so, you know, practically part of the family, sorta, I mean, not that we ask Him over for Thanksgiving or anything, but...

[Extended silence. Awkwaaaaard.]

Maybe I should strengthen my friendship with Christ before using His name for my gain, huh?

Go back and read John 15:16. Better yet, check out some more of the context by looking at John 15:14-17:

14 You are my friends if you do what I command. 15 I no longer call you servants, because a servant does not know his master's business. Instead, I have called you friends, for everything that I learned from my Father I have made known to you. 16 You did not choose me, but I chose you and appointed you to go and bear fruit — fruit that will last. Then the Father will give you whatever you ask in my name. 17 This is my command: Love each other. — John 15:14-17 NIV (emphasis added)

Think my fictitious scenario above exaggerates too much? I'm not so sure. See what Jesus says in Matthew about folks trading on his good name without the fruit to justify it:

18 A good tree cannot bear bad fruit, and a bad tree cannot bear good fruit. 19 Every tree that does not bear good fruit is cut down and thrown into the fire. 20 Thus, by their fruit you will recognize them. 21 "Not everyone who says to me, 'Lord, Lord,' will enter the kingdom of heaven, but only he who does the will of my Father who is in heaven. 22 Many will say to me on that day, 'Lord, Lord, did we not prophesy in your name, and in your name drive out demons and perform many miracles?' 23 Then I will tell them plainly, 'I never knew you. Away from me, you evildoers!' — Matthew 7:18-23 NIV

Are you just name-dropping Jesus? Man, sometimes I do. I've witnessed the power of prayers made in His name and in a spirit of obedience, but I confess that many times my name-dropping is just bogus. I need to work on that — need to work on my friendship with Christ, need to work on my obedience to His commands, need to work on bearing fruit, and need to work on loving my neighbor — because I definitely don't want to experience any awkward encounters with God. How about you?

Thursday, November 12, 2009

Harrisburg Area Land Use Planning kick-off meeting

Tonight I attended my very first civic community meeting, a kickoff meeting focused on the Harrisburg Area Land Use Planning effort. The meeting was a couple of hours in length, and drew what I would guess to have been about 150-200 people (though I'm really bad at estimating such things). I thoroughly enjoyed myself there — enjoyed seeing other folks in attendance that I know, enjoyed meeting some new folks (including our town's mayor), and enjoyed feeling like I was participating in something of value to my community. I learned several things about my town that I didn't know beforehand. And overall, it was a good opportunity to just listen to what others in my community think about the direction our town is heading.

Harrisburg, NC has in recent years been at odds with itself about land use. Our residents are fortunate to have some of the highest personal income levels in the area, and the town offers some of the lowest tax rates in the area. But we're growing like mad, and that necessarily has town planners busy, you know, planning to accommodate that growth. But how that growth happens has become a bit of a sticking point. It's easy to find folks with extreme opinions about the matter. Many oppose "big-box" commercial development, citing concerns about increased traffic, crime, and low-paying jobs probably filled by folks that can't afford to live in the town itself. Many others are begging for the entrance of large-scale commercial development, hoping that tax revenues from such places will fund the town's growth so that increased personal property taxes don't have to. Some read the phrase "bedroom community for Charlotte" with disdain; some with delight. Reconciling these viewpoints will certainly prove challenging for those tasked with doing so.

I look forward to the next meeting in this series, though I'm more than a little concerned that as the presentations and discussions progress from the general to the specific, these will devolve into battles of opposing viewpoints. Tonight's meeting intentionally cast absolutely no direction, at all, for the town. And yet there were already plenty of folks willing to voice strong opinions about how things ought to be, some of which were definitely assuming a defensive position. That's really not helpful. If you are a Harrisburg resident and happen by some misfortune to have wound up on this blog post, please, please do your fellow citizens the courtesy of not assuming that they want to ruin your quality of living — while a perfect solution that pleases everyone might not be possible to achieve, you can be pretty sure that forsaking honest communication for bickering will hinder the creation of even a tolerable solution.

(Oh. And no, Mom and Mom-in-law, my attendance at this meeting does not mean that I'm gearing up for a bid on a Harrisburg Town Council seat. It was just another way to connect with our community. Sorry to disappoint.)

Wednesday, November 4, 2009

ApacheCon: Where Subversion, Apache, and 100% Cotton intersect

Today during the opening ceremonies of the U.S. ApacheCon 2009 conference, Hyrum Wright (President of the Subversion Corporation) and Brian Behlendorf (a representative of both Apache and CollabNet's Board of Directors) made a joint announcement that the Subversion project was immediately seeking acceptance in the incubation process at the Apache Software Foundation.

Thanks to CollabNet's generosity (and my wife Amy's general coolness about my occasional business-related travel), I was able to be present for this historical event. Also, I was fortunate to have been given the opportunity to design the official commemorative T-shirt of the event:

It's not the cleanest thing I've ever done graphically. I really, really like the striped front. But I was tasked with conveying an awful lot of information (the 10-year anniversary of the ASF, Subversion's fit into the mix of other Apache projects, CollabNet's history as founder and primary corporate sponsor of the project, and so on), and the resulting busy-ness of the back's design unfortunately conveys that fact. Still, not too shabby for short-deadline (like, three days) work.

Tuesday, November 3, 2009

SubConf/Munich 2009

As I compose this, I'm 38,000 feet above sea level and somewhere between Charlotte and Denver, en route (ultimately) to this year's U.S. Apachecon event. Seems it was just yesterday that I was flying home from my last conference event. Perhaps that's because it was just a few days ago that I passed through Customs in Charlotte after the lengthy flight home from Munich, Germany. I'd been in Munich for the third SubConf Subversion user conference. I've had the pleasure of attending the prior two years as well, and this year's event was again a enjoyable one.

After helping to coach Gavin's soccer team to an 8-1 victory last Saturday, I hurried home, grabbed my bags, and was off to the airport. My direct flight from Charlotte to Munich landed Sunday morning around 8:30am local time. A couple of train rides and a short walk later, I was checking into the B & B Hotel, where (I was told) "all the cool kids" — that is, some fellow Subversion developers — were staying. I spent Sunday afternoon getting settled into the hotel and resting, then met up with Hyrum Wright for the express purposes of reprising last year's trip to Berni's Nudelbrett and to plan how we'd invest our time on Monday.

Hyrum and I decided on a trip to Salzburg, Austria for our Monday outing. It was two hours away by train, so we caught the earliest one we could manage. While in Salzburg, we visited the Hohensalzburg Fortress (an 11th-century fortress that overlooks the city), the Residenz State Rooms, Mozart's birthplace, and some other spots in the city. Afterwards, we took a bus out to the town of Grönig, where we rode the Untersberg Cable Car up into the mountains. Wow! Suspended above the earth by a wire the thickness of my forearm, watching as rocky crags passed underneath, I was overwhelmed by the novelty of it all. This was not a normal day in the life of Mike Pilato, to say the least. Our train back to Munich got us in town in time for dinner, which we took at one of the city's many beerhouses. (Thankfully, the locals don't take it too personally when we tourists opts for Coke and Fanta.)

I returned to the hotel around 10:00pm, where two things were waiting for me: a group of Subversion developer colleagues, and a nasty surprise from the SubConf event organizers. It seems that an employee of Polarion who was slated to present an all-day Subversion workshop the following day (Tuesday) fell ill, and then made the poor decision to use email — nice, asynchronous, non-interrupting, unacknowledged email — as his medium for telling the event organizers that he had to bail on the workshop. By the time they realized that they had no one to present the workshop, the organizers had to scramble for assistance. They found me online and asked if I could present the workshop instead. I was completely unprepared to do so, but offered to help as best as I could.

Fortunately, things took a turn for the better when I then went down to the lobby to meet up with my colleagues. While I was bemoaning this situation and my lack of preparedness, the angel Michael — no, not that one; Michael Diers (from Elego) — offered to assist me for the first half of the day-long workshop and to take over entirely in the latter half. And as if that wasn't great enough, I was then presented with the finished results of the T-shirt I designed for the conference:

Tuesday's workshop went pretty well, actually, thanks largely to Michael's familiarity with the topic and ready-on-hand materials. After lunch I was finally able to meet up with several other Subversion developers in a room the conference organizers had arranged for us to occupy for hackathon purposes. We worked for a few hours before heading over to participate as a panel in a Developer Roundtable event — an hour and a half of face-to-face interaction with Subversion users and administrators interested in learning more about Subversion's upcoming features or in solving particular Subversion problems they were having. I love these events for the fact that they serve to remind me that at the other side of every bug report or feature request is another human being who isn't just trying to make work for us as developers but is merely trying to get stuff done.

Wednesday morning, I delivered my keynote presentation, The Subversion Legacy (So Far...). I took the attendees on a brief walk through Subversion's history, beginning with its instantiation as an open-source project by CollabNet and continuing through to the current day, and focusing on aspects of the community and of key events and decisions which have contributed to Subversion's success. Despite the language challenge (most of the attendees were more comfortable communicating in German), I got positive feedback. And with that completed, I was in the clear in terms of obligations to the conference, and joked that I was now able to return to my typical 40% stress level.

I spent the rest of Wednesday and most of Thursday working on Subversion itself in the hackathon room with the other developers. We had occasional breaks to take in presentations by our peers, but mostly spent the time trying to improve the very software that the conference existed to celebrate. Thursday night those of us that remained went to dinner in Munich, sharing a final last few minutes together. A casual onlooker would never guess that we live scattered across the globe, only occasionally seeing each other in person. (In fact, I met one of my CollabNet colleagues for the first time on this trip!)

I traveled to the airport Friday morning with Greg Stein, hopped onto my plane bound for Charlotte, and was fortunate to sleep two-thirds of the flight away. I was greeted in Charlotte on Friday afternoon by my incredible, amazing wife and children. The opening theme of my keynote was about gratitude, and gratitude for good friends and a loving family served as the bookend to that week-long trip to Germany.

Monday, October 5, 2009

Soccer Monsters

I don't know why, but my oldest son's soccer team chose the name "Soccer Monsters". I have trouble prioritizing how I spend time, so for kicks, I whipped up (with the assistance of Amy's valuable feedback and suggestions) a team logo:

The coaches liked the result. Now our little 5- and 6-year-old soccer stars are sporting embroidered patches of the logo on their jerseys (thanks, Patches4Less), and slappin' stickers of the logo all over the place (thanks, Contagious Graphics).

Sunday, October 4, 2009

Review: Main Street Steak & Seafood, Harrisburg, NC

At the core of every pessimist's belief system is a simple truth: if you expect the worst, you'll only get pleasant surprises. At the core of every realist's belief system is another: if you expect the worst, and consistently receive it, pessimism might just be warranted.

Long ago, 4351 Main Street, Suite 111 — located in Harrisburg's Town Center — held Ciro's Italian Restaurant. Amy and I lived in Chicagoland at the time, and were only able to visit that establishment once. I recall enjoying it and remarking that it was much like having an Olive Garden in Harrisburg, but without the cookie-cutter chain restaurant feel. But eventually Ciro's moved out of that space, making way for a new tenant: Parma Ristorante. Now, my understanding is that Parma was actually a reincarnation of a separate restaurant (Roma's) which had previously occupied a location on the outskirts of the town. We had friends who swore by Roma's pizza, but our own experiences there were mediocre at best. Sadly, mediocre took a turn for awful when Parma opened up. This isn't a review of Parma, and perhaps it isn't kind to speak of the dead, but suffice it to say that despite multiple opportunities to impress us during visits to that shop — even across its various management and ownership changes — it not only failed to impress, but it failed to even remotely please. Parma was, quite simply, a monumental culinary disaster.

When Main Street Steak & Seafood opened its doors a few weeks ago in the old Ciro's/Parma location, we looked forward with cautious optimism to trying it out. That optimism was quickly crushed by the terrifying review of the establishment that we received from some good friends. Their nightmare-ish experience at the place — which ultimately resulted in them having to cancel subsequent plans for their evening — was one for the storybooks. If I recall correctly, the only positive thing that could be said was that the dessert tasted good. And even that was bittersweet, as said dessert was delivered in unrequested take-home boxes! So, as you can probably imagine, it was with justifiable pessimism that my wife, Amy, and I wandered into Main Street Steak & Seafood last night.

Our first impression of the restaurant was not exactly ideal, though in fairness, only some of that could be helped. The orientation of Suite 111 in that building is such that the restaurant doors are on what could arguably be considered the back side of the restaurant. I've got a whole set of opinions about the design of Harrisburg's Town Center that aren't particularly relevant here, but again, this is just what Main Street S & S has to work with. What can be improved is not allowing a number of staffers to sit in a bench near the hostess stand with their backs to the window awaiting incoming customers. Even if there isn't always something to be done in a restaurant, the customers need to think there is.

The restaurant was busy, but not crowded. Several staff members were bustling about, doing their thing. One got the sense that the place was alive — not quite abuzz, but definitely alive — with activity. Gone were the old Tuscan tones of Ciro's and Parma. New cuisine demands new decor, and MSS&S has opted for a more contemporary blue and silver look, sparsely accented with iron works and some somewhat out-of-place looking fish caricatures. Modern jazz music added to the ambience, playing at appropriate levels — even though we were seated directly beside the kitchen, we heard more of each other than of the music, and more of the music than of shuffling pots and pans. As this was a rare chance for Amy and I to have a dinner without our kids, "more of each other" was a big plus for us.

Soon after we were seated, our server, Chad, greeted us and took our drink orders. While the wine list appeared to be about a page long, we opted for soft drinks on this evening instead. Chad returned with the drinks (served in unassuming glassware) a short while later, bringing a basket of breadsticks as well. We needed some extra time to decide on our orders, and Chad granted us that without disappearing into that abyss that often consumes other waitstaff in similar situations. Amy and I eventually decided to opt out of an appetizer, hoping to save some room for dessert. Chad took our dinner orders, and then set off to register them with the kitchen while we set off to munch on the rather tasty breadsticks.

Our salads were delivered quickly, and were much larger than we expected for the $2 paid for them. Amy went the garden-salad-with-balsamic-vinaigrette route, and she was pleased by the thick dressing and (again) the large portion. My Caesar salad was good, too, but even though I could see that the dressing was thoroughly mixed throughout the greens, I wasn't able to taste it in my first several bites. I suspect it was mixed when the lettuce leaves were still wet from washing, which watered the taste down below the threshold of detectability. But as I settled into the salad, that Caesar dressing taste began to appear. In the end, it was largely forgettable as salads go. But forgettable is actually quite fine when you've every reason to expect much, much worse.

Our entrees arrived just as Amy (who is a slower eater than I am) was finishing her salad. We had chosen entrees that we were familiar with so that we could have some point of reference for comparison. Amy's filet mignon was cooked properly and accompanied by smashed potatoes and mixed vegetables. We were surprised to see yellow carrots amongst the mixed vegetables — those aren't common in area restaurants. Amy had positive things to say about her entree's taste, the portion sizes of the sides, and the cool plate all of this was served on. Her only negative comment was that she felt the veggies might have been improved with some seasoning. My oscar-style grilled salmon was also properly cooked, flaking apart as I expected without any detectable dryness save for a small, thinner corner section. It was topped by asparagus that, too, was well prepared — al dente enough to remain crisp and encourage knifework, but soft enough to drape across the salmon fillet. I, too, had the smashed potatoes, which weren't the garlic mashed I'd hoped were available, but which served their starchy purpose.

The main course came to a close much as it often does: my plate empty, and Amy's only halfway so. Here we learned the downside of those "cool" plates: those suckers are heavy. We asked Chad for a take-home box for Amy's leftovers, but the restaurant should strongly consider having the servers perform the transfer of food to boxes instead of leaving the customers to deal with those heavy plates themselves. Once the leftovers were boxed, Chad gave us the dessert selection. The options were fairly straightforward — no fancy dessert names evoking imagery of volcanoes, tropical destinations, or one's own demise. "Chocolate cake" was the first mentioned, and I'm not sure were even paid much attention to the rest of the list because clearly (to my wife, anyway) it was a night for chocolate. They were out of ice cream, so we ordered a coffee accompaniment. Chad returned shortly thereafter with a whopping chunk of 3-layer cake, drizzled with chocolate and raspberry sauce (and, of course, our coffee). Here Amy's and my opinions diverged. That the cake was served chilled was to her a great thing, somehow balancing out with the hot coffee in her universe. Me? I want soft, moist, and warm cake. I want the chocolate to ooze, the icing to drip, and to feel like I need to keep a spoon on standby when the fork can't keep up with the whole lot of the liquefying mess that ensues. This fact, however, did not prevent me from performing my husbandly duties and eating 49% of the cake. Warm, cold, or otherwise, it was a tasty cake. Then upon our request, Chad provided us with the bill, and that was that.

Overall, our visit to Main Street Steak & Seafood was nothing like what we expected. In stark contrast to the experiences of our friends, the service we received was outstanding. Food-wise, I can't say that anything we had was unique or inspirational, but perhaps that's okay right now. Maybe playing it safe and establishing a client base is wise given the disappointing track record of the previous establishment. I would certainly encourage the management to consider some more creative options, though, perhaps offering the entrees with choices of cooking styles and/or sauces. As for Amy and I, we welcome this new addition to Harrisburg's foodscape, and look forward to returning for another visit some time.