Here’s a real-world situation that tells you why I’m falling in love with darcs.
I’m working on a plug-in that logs all notifications posted by Apple Mail to a couple of files. The idea of this plug-in is to enable Mail-bundle developers to develop more reliable plug-ins by listening for notifications rather than posing as Mail’s classes or swizzling its methods.
(As you know, I don’t ordinarily announce what I’m working on before it’s ready; for this post, it’s important to provide context.)
The first revision of the plug-in used NSLog, but I found that this spammed console.log rather heavily. So I changed it to use two separate log files, which I write to using NSFileHandles.
Then I started work on a new feature: datestamps. While working on that, however, I noticed that I had forgotten to close and release my two file handles in -dealloc
. Oops.
Now, remember that I had local changes. If this code were versioned in svn, I would have to:
- bzip2 the source file (which renames it as a side-effect).
- svn up the file in order to restore the pristine copy.
- Open it in a separate editor (so as not to lose undo history) and add the
closeFile
and release
messages that I’d forgotten.
- Save and exit.
- Commit.
- Delete the committed file and bunzip2 my original one.
- Go through an svn diff and redo the fix in my modified file so I don’t clobber the changes in my next commit.
What a hassle. But darcs has first-class support for just this situation.
All I had to do was darcs amend-record. darcs asked me whether the most recent commit was the one I wanted to amend, then it offered me the choice of which hunks of local changes I wanted to include in the amendment. I said yes to the one with the closeFile
and release
messages and no to all the others. That’s all I had to do.
Let me summarize that for you: I was able to retroactively fix my previous commit while I had other local changes in the same file, without sweeping up those other changes into the commit.
That’s awesome.