Thanksgiving Computing

Just remember: nothing says traditional Thanksgiving like the Honeywell H316 Pedestal “Kitchen Computer”.

Happy Thanksgiving

As my American readers sit down to enjoy a happy Thanksgiving meal, I wanted to take a moment to wish everyone a wonderful holiday season.

Dropbox on the iPhone

I’ve been a big fan of Dropbox, a completely seamless remote storage solution, since they first had their closed beta. They provide two gigabytes of storage for free, have native clients on Mac, Windows, and Linux (including 64-bit!) that Just Work™, and have a ridiculously clean website that makes seeing a history of changes, and even restoring deleted files, wonderfully simple.

Recently, Dropbox has been getting some love for how awesome it is, and as I was poking through Hacker News comments on the service, I discovered yet another reason Dropbox rocks: they have an iPhone interface that lets browse your photos and documents, and see any recent changes to your folders. Basically, anywhere you have an iPhone, you have access to your Dropbox.

It’s little things like this that make me think I really should have gotten an iPhone instead of a Blackberry Pearl.

Rebasing in Mercurial

So, you’ve adopted git. Or maybe Mercurial. And you’ve started to use it. The problem is, every other commit reads some variant of, “Merged with stable,” “merged with base,” or some such. These commits convey no useful information, yet completely clutter your commit history. How do you make your history more useful?

The answer lies in rebasing. Rebasing is a technique made popular by git where you rewrite your not-yet-pushed patches so that they apply against the current remote tip, rather than against the tip of the repository you happened to last pull. The benefit is that your merge history shows useful merges—merges between major branches—rather than simply every single merge you did with the upstream repository.

Talking to a colleague of mine today about the upcoming features in Mercurial 1.1, I was surprised to hear him say, “Oh, great, so Mercurial will finally have rebasing!” Well, while the next version of Mercurial does add a pull --rebase command, all it does is automate some mq bookkeeping behind the scenes. If you want, you can do that mq bookkeeping explicitly right now.

Let’s take a look at my Copilot development repository, for example:

gozer:Host benjamin$ hg out
comparing with ssh://fcs//hg/copilot-helpers-devel
searching for changes
changeset:   1937:fe42e5e8e0cf
user:        Benjamin Pollack <bpollack@fogcreek.com>
date:        Mon Nov 24 14:49:30 2008 -0500
summary:     Make CPUpgrader a proper framework so that OneClick can include it

changeset:   1938:20033e199dc7
user:        Benjamin Pollack <bpollack@fogcreek.com>
date:        Mon Nov 24 20:08:06 2008 -0500
summary:     Undo accidental rename of Host to OneClick

changeset:   1939:127619345a57
tag:         tip
user:        Benjamin Pollack <bpollack@fogcreek.com>
date:        Mon Nov 24 20:12:39 2008 -0500
summary:     Add OneClick

gozer:Host benjamin$ hg in stable
comparing with ssh://fcs//hg/copilot-helpers-stable
searching for changes
changeset:   1940:6db7e59a82c5
tag:         tip
parent:      1936:3140f971d7ab
user:        Benjamin Pollack <bpollack@fogcreek.com>
date:        Mon Nov 24 12:38:14 2008 -0500
summary:     Added tag 000253 for changeset 3140f971d7ab

gozer:Host benjamin$

So, I’ve got three outgoing changes, and one incoming change—and the incoming change is just a tag addition. Having an explicit merge is overkill and simply clutters my history; there’s no benefit to having it listed. It’s the perfect candidate for a rebase commit.

Our battle plan, then, is as follows:

  1. Import all outgoing patches to mq patches
  2. Pop them off the patch stack
  3. hg pull from the stable repository
  4. Reapply my outgoing patches
  5. Convert my patches back into Mercurial changesets

Let’s give it a shot. My base commit is changeset fe42e5e8e0cf, so I need to import everything between that and tip into mq and then pop it off:

gozer:Host benjamin$ hg qimport -r fe42:tip
gozer:Host benjamin$ hg qpop -a
Patch queue now empty
gozer:Host benjamin$

If everything was successful, I should have no outbound patches…

gozer:Host benjamin$ hg out
comparing with ssh://fcs//hg/copilot-helpers-devel
searching for changes
no changes found
gozer:Host benjamin$

…and we indeed see that’s the case. That means I can now simply hg pull -u from the remote repository…

gozer:Host benjamin$ hg pull -u stable
pulling from ssh://fcs//hg/copilot-helpers-stable
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
gozer:Host benjamin$

…and then reapply my patches, and convert them back to changesets:

gozer:Host benjamin$ hg qpush -a
applying 1937.diff
applying 1938.diff
applying 1939.diff
gozer:Host benjamin$ hg qdelete -r qbase:qtip
gozer:Host benjamin$

And finally, verify that it worked as expected:

gozer:Host benjamin$ hg glog -l 4
@  changeset:   1940:0b08e0a83965
|  tag:         tip
|  user:        Benjamin Pollack <bpollack@fogcreek.com>
|  date:        Mon Nov 24 20:12:39 2008 -0500
|  summary:     Add OneClick
|
o  changeset:   1939:a730a92acb01
|  user:        Benjamin Pollack <bpollack@fogcreek.com>
|  date:        Mon Nov 24 20:08:06 2008 -0500
|  summary:     Undo accidental rename of Host to OneClick
|
o  changeset:   1938:01954591e76e
|  user:        Benjamin Pollack <bpollack@fogcreek.com>
|  date:        Mon Nov 24 14:49:30 2008 -0500
|  summary:     Make CPUpgrader a proper framework so that OneClick can include it
|
o  changeset:   1937:6db7e59a82c5
|  user:        Benjamin Pollack <bpollack@fogcreek.com>
|  date:        Mon Nov 24 12:38:14 2008 -0500
|  summary:     Added tag 000253 for changeset 3140f971d7ab
|
gozer:Host benjamin$

Perfect. I have a linear history, and have rebased my changes on top of the remote tip.

It’s definitely more involved than hg pull --rebase, but if you don’t want to wait for Mercurial 1.1, you’ve got the same functionality available right now.

Why QA is Important

QA’s one of the most important parts of any software development project, so I’m profoundly saddened by how often it’s overlooked. Thankfully, Copilot has a solid QA process, so when we release software, I can generally be confident that it will work as-advertised.

Tricks with mq

Last night, I realized that I had accidentally made some commits to one of my Mercurial repositories without an email address set, meaning that they all showed up as benjamin@localhost. Since the repository’s private, and I wasn’t worried about destructively rewriting history, I wondered, can I fix this using mq?

The answer was a resounding, “yes.”

First, let’s bring the entire history into mq, and save the result so that we have something to go back to in case we screw up:

~/code/bqb$ hg qimport -r 0:tip
~/code/bqb$ hg qci -m "Before address change"

Next, because we’re about to rewrite the patches themselves, we’ll pop off all of the patches:

~/code/bqb$ hg qpop -a

at which point we can safely go and make our changes with some simple sed magic.

~/code/bqb$ cd .hg/patches
~/code/bqb/.hg/patches$ sed -i -e "s/@localhost/@bitquabit.com/" *.diff
~/code/bqb/.hg/patches$ hg diff

Everything looks okay, so it’s time to reapply the patches:

~/code/bqb/.hg/patches$ cd ../..
~/code/bqb$ hg qpush -a

and convert them back into changesets.

~/code/bqb$ hg qdelete -r qbase:qtip

Did it work?

~/code/bqb$ hg log | grep '@localhost'
~/code/bqb$

Yep. We’re all set.

A couple of things to keep in mind if you do this:

  1. Just to state the obvious, you’re rewriting history. You will no longer be able to interact with repositories made before the rewrite. This means you should never try the above stunt on a repository you’ve shared with others. (Well, mostly. If you only run the initial qimport on changes you’ve not yet pushed out—rather than on the entire repository, as I did—you’re fine. Just be careful.)
  2. Make very sure you’ve set Mercurial to use git-style patches, or you will unwittingly annihilate blank and binary files when you convert your changesets to patches. If you’ve not yet done so, edit your ~/.hgrc so that -g is passed by default to qimport and qrefresh.
  3. Remember that whenever working with mq, you have the potential to completely lose your history. Be careful. Use hg qci to back up known-good patch states early and often.

TED Talk on the Third World

This is an amazing, riveting talk on the progress—both social and economic—that has been made in the Third World. If you vote, if you’re active in politics, you need to watch it.

Why I Love Meetings

Learn why I love meetings over at the Copilot blog.

Rachmaninoff Had Big Hands

I don’t want to get into the habit of posting videos, but having played a lot of Rachmaninoff when I was younger—including Prelude in C# minor, Op. 3, No. 2—this video had me in hysterics:

For the record: when I last played the piece, I couldn’t play the full chords, either.

(Courtesy of The Old New Thing)

Minority Report in Real Life

A company named oblong has implemented the Minority Report computer interface in real life:

You can read more on their corporate blog.

Guide to Deploying Seaside on Linux

While I’ve gotten pretty good at deploying Squeak and Seaside behind Apache, I remember that the first time I tried it, I got horribly confused and frustrated by the lack of any simple, easy-to-follow guide. Well, if your virtual host runs a Debian-based distro, now you’ve got one: Peter Osburg has provided a step-by-step guide to deploying Seaside apps behind Apache using reverse proxies. The directions should be mostly applicable to other Linux distributions as well.

The Impact of Gay Marriage

I have to confess, this is roughly my take on the situation. I’m not especially clear on what the hullabaloo is about.

Phones and Bovines

Would we recommend the Storm? If you’re locked into a contract with Verizon, want a touchscreen phone, and are willing to put up with an OS that moves like a tranquilized yak, then yes the Storm is for you.

Not exactly the rousing endorsement that Verizon and RIM were hoping for, I think, but consistent with what I expected. Verizon is utterly terrified of giving up any control over its cellular network. That may seem like a good idea in the short term, but with T-Mobile and AT&T making non-trivial concessions to consumers, both in features and flexibility, it can only work for so long.

bitquabit 3.0 Beta

Well, bitquabit 3.0 is slowly coming online. The new blog is up and mostly functional, the new landing page is in place, and soon my independent coding escapades will be fully onlne. In the meantime, feel free to follow along over at my bitbucket account.

Free Books on Programming Linux

When I was a junior at Duke, we had to make some changes to the Linux kernel for my OS class. Unfortunately, I was the only one who’d had much experience in Linux before, and our professor seemed to think that providing any instruction about how Linux’ kernel worked—or even how Unix programs in general worked—would be overkill. Even great coders will fail if not provided any guidance how to solve a problem.

At the time, our options were to spend serious cash on books, or to struggle along through mailing lists until we can find the answers we needed. We went with the second option, but if you find yourself in a similar boat, there are now decent low-level books on Linux programming available online for free. I only had a chance to look at the chapter on interprocess communication, but assuming the rest of the book’s at the same quality, it should be a solid reference for someone starting Linux programming for the first time.

Ubuntu 8.10: Fonts Done Right

I recently upgraded my laptop to Ubuntu 8.10, and amazingly, Ubuntu just went from one of the worst font systems I’ve seen on any system to the best I’ve seen on any system. They seem to have taken Microsoft’s ClearType technology and improved upon it surprisingly well.