svnhome take three

Oddly enough, like Danny O’Brien, I spent a good chunk of the holiday weekend reworking my version-controlled home directory setup. This is my third time setting up a revision-controlled home directory, and I think I’m starting to converge on something fairly workable.

In my first attempt, way back when, I used CVS. After a while, that got to be fairly painful to keep up, and eventually I dumped everything out and lived without revision control for a while. In the end, that was just as bad or maybe even worse, so I returned to the “revision control uber alles!” position – only by now, SVN with the fsfs backend was available, so I used that.

Initially, that was good. I had (almost) everything in a single repository and a whole mess of scripts, symlinks and svn:external relationships holding the whole thing together. Every computer that I used had a checkout of some subset of this repository, and when I needed to set up a new computer, it was a matter of just a few minutes to bootstrap up the basics. The downside was that adding a new project was a pain in the ass, and getting it added in to all the various host setups where it needed to be was worse. The goal of the design was to allow different chunks of stuff on different computers – but in the end it turns out that almost all the chunks end up on almost all the computers anyway. Over the past month, I’ve been coming to the realization that I’ve not only optimized the corner case (adding a new host to the setup is fast, but I don’t really get access to new computers all that often, it turns out), I’ve also pessimized the common case (I add new projects all the damn time). When I got to the point where I was avoiding putting a new coding project into the right place in the repository because I didn’t want to jump through the hoops, I knew it was time to start over.

In the process of reworking the system, I’ve picked up a scar or two learned a few lessons about structuring SVN repositories, and I’ve ended up going away from the ‘one big repo’ pattern. One of the goals of the new design was to make it possible to allow more public access to my repositories. Since not everything can get dumped publicly right away, I’ll be doing some repository dumping and loading as I get things cleaned up – and dumping and loading parts of repositories is a pain. Much easier if everything is structured in small repositories to start with; then you can just dump and load at the repository level, which seems much more in line with how those tools want to work.

Another aspect of the design, related to being more public, was an increased usage of Trac instances, one per public project. I have the beginnings of what will turn into a ‘create new project’ script which will hopefully make the common case friction-free. There’s still a lot of utility scripting to be done around this system, but it’s young enough that it’s not completely clear where the automation wins are going to be.

My overall home directory organization is largely unchanged from the last go-round – having things in fairly standard UNIXy subdirs works well for me. The private dir is new this time around, because there are some things that you can’t share with everybody.

bin      # uncontrolled; primarily automatically generated symlinks
doc # private svn repository
etc # public svn repository for configuration -- bash, vim, etc.
lib # uncontrolled; mainly locally installed emacs modules
private # repository for private configuration details -- passwords, etc.
proj # contains one dir per project; each dir is a distinct repo.
# some public, some private
src # private svn repo of frequently used tarballs
tmp # the junk drawer
var # uncontrolled; logs

The public stuff is available for read-only access at If you see anything that you think shouldn’t be up there, do me a favor and holler back. Alternatively, if you see anything that you’re interested in hacking on – like the Catalyst-based browser-oriented RSS feed reader that I’ll actually release to CPAN one of these days, let me know and I’ll get you a commit bit.