Sometimes, it’s useful to see what subversion’s actually doing when talking to a server. There’s a neon-debug-mask option in ~/.subversion/servers. But what values can it take? They’re not documented in the subversion manual.

As always, the source is informative.

/* Debugging masks. */
#define NE_DBG_SOCKET (1<<0) /* raw socket */
#define NE_DBG_HTTP (1<<1) /* HTTP request/response handling */
#define NE_DBG_XML (1<<2) /* XML parser */
#define NE_DBG_HTTPAUTH (1<<3) /* HTTP authentication (hiding credentials) */
#define NE_DBG_HTTPPLAIN (1<<4) /* plaintext HTTP authentication */
#define NE_DBG_LOCKS (1<<5) /* WebDAV locking */
#define NE_DBG_XMLPARSE (1<<6) /* low-level XML parser */
#define NE_DBG_HTTPBODY (1<<7) /* HTTP response body blocks */
#define NE_DBG_SSL (1<<8) /* SSL/TLS */
#define NE_DBG_FLUSH (1<<30) /* always flush debugging */

Or if you’re not a C coder (or had to spent more than 3 seconds working it out like me):

raw socket
HTTP request/response handling
XML parser
HTTP authentication (hiding credentials)
plaintext HTTP authentication
WebDAV locking
low-level XML parser
HTTP response body blocks
always flush debugging

These are summed to enable the features you want. So, if I want requests, responses and bodies, that’s 2+8+128, so I need this in ~/.subversion/servers:

neon-debug-mask = 138

Of course, interpreting the resulting output is up to you, but if you’re having difficulties, it may give you some clue what’s up. I can immediately see the large “log” command that git svn rebase is using for instance.


Commit Messages

I’ve been using git for most of this year. It’s been a really excellent ride, and the things it enables are wonderful. But one of the things I’ve found most handy is a convention.

The commit message is treated like an email: one line of subject and then a few paragraphs of explanation. Keep the subject line short so you don’t have scroll bars when they’re displayed.

This works really well for scanning the history of a project — you can get at at a glance overview of what’s changed and then click on a single commit for more detail. I’ve tried to carry this over to subversion projects as well.


The best subversion client

The best subversion client I’ve used to date? git. It’s so script-friendly! This morning somebody asked me for a complete history of a project in CSV format. Using my nicely cloned repository, it was a simple matter of giving the correct format to git log.

  ⇒ git log --pretty='format:%h,%ai,%an,%s' | head -5
  f584913,2008-09-26 21:58:02 +0000,Dominic Mitchell,Pull out a base class for OptionInstances.
  803a32a,2008-09-26 21:57:38 +0000,Dominic Mitchell,Organise imports.
  1cb0132,2008-09-26 21:57:17 +0000,Dominic Mitchell,Switch from a Set of OptionInstance to a Map from Option to OptionInstance.
  a0c1efd,2008-09-26 21:56:56 +0000,Dominic Mitchell,Introduce OptionInstance.
  a211ae3,2008-09-26 21:55:59 +0000,Dominic Mitchell,Use standard idiom for emptying a Set

I love how git embodies the Unix toolkit approach.


Managing 3rd Party Code

I’m in a pickle. There’s a project at $WORK that I should have been paying closer attention to (but haven’t). We’ve taken some 3rd party software (guanxi as it happens), and made some modifications in order to form our own custom distribution. But:

  • We started modifying what was then the trunk.
  • The trunk has moved forwards.
  • Our modifications are not isolated chunks of work (though they should be).

In other words, it’s a classic merge scenario. Except that both our changes and the trunk are contained within a CVS repository. This means that the original ancestor (the point at which divergence started) can be somewhat difficult to ascertain.

Thankfully, I’ve had moderate success using git cvsimport to pull everything into a git repository. Well, actually five git repositories, thanks to git cvsimport not quite understanding CVS’ modules file format. So, git merge should assist me. But of course, I’m unfamiliar enough with the guanxi code to know how to successfully resolve conflicts. Best of all, it looks like new development which is similar to ours is happening on a branch destined to go into the trunk.

Where does this leave me? For now, a long session of merging with the developer who did the changes. But longer term, we also need to:

  • Split out our code changes into their own packages (or for preference, project).
  • Regularly merge in changes from trunk.
  • Talk to the original developer about whether or not he can make life easier for us.
  • Switch to using git proper rather than developing in the original CVS tree.

It doesn’t help that the project in question is a Java webapp — we want to reuse the classes in that webapp as a jar file in our own webapp. This is yet another complicating factor…

My head hurts.


git branches with subversion

I like using git, particularly in combination with git svn. It makes it really easy to work with version control offline. But there’s a problem: branches.

Now git is really good at using branches. Unfortunately, git svn can’t cope very well with pushing one of git’s merges back into subversion. It gets really confused. Trust me.

Thankfully, I’ve found an easy way to do it: patches.

In the git format-patch man page, there’s a useful example:

  % git format-patch -k --stdout R1..R2 | git-am -3 -k

That is, make a mailbox full of all the changes between R1 and R2, then apply them to the current checked out branch. Essentially, “copy the changes on that branch to this one”.

I just needed to do this with a project I’ve been playing with. I’d been working on a branch proper-xml-generation. In order to merge it, I had to:

  1. Rebase that branch on the master, so I know that there won’t be any conflicts.
    • git checkout proper-xml-generation; git rebase master
  2. Switch back to the master branch.
    • git checkout master
  3. Copy the patches.
    • git format-patch -k --stdout master..proper-xml-generation | git am -3 -k
  4. Pump the results back into subversion.
    • git svn dcommit

And hey presto, the branch is back in subversion. It looks a bit weird having 14 commits in a few seconds though.

The main disadvantage of this is that it’s pretty much a one-time push back into subversion. You don’t get all the nice usual features of git, where you can make more changes on the branch and merge them. But it’s been sufficient for me for a little while now, so I thought I’d share it.


Google Code Hosting – svn import

I’ve just started a new project on Google Code Hosting (of which more later). I’ve been developing it in a local svn repository, and I’d like to transfer it up to the google svn server.

This isn’t easy. Google help has How do I import an existing Subversion repository?, but that’s only half the answer. The problem is that I develop many projects in one single repository (I find it easier to manage). So I wanted to export a subset of my repository to google.

Sadly, svnsync doesn’t support that.

The workaround is simple (yet tiresome). You have to create a mini-repository containing just the subset of the original repository you want, then send that to google. This is what I came up with to export just /project.

  % svnadmin create /tmp/project-repos
  % svnadmin dump -q /home/svn/public |
  > svndumpfilter include /project --renumber-revs -drop-empty-revs |
  > svnadmin load -q /tmp/project-repos

Of course, now that I have the subset isolated, the path structure is wrong. Everything is living under /project/trunk instead of /trunk. So, we have to fix that.

  % svn mv file:///tmp/project-repos/project/trunk file:///tmp/project-repos/
  % svn rm file:///tmp/project-repos/project -m 'No longer needed.'

Finally, I can use svnsync to send the changes to google:

  % svnsync init --username file:///tmp/project-repos
  % svnsync sync --username file:///tmp/project-repos

Phew. What a palaver. It would have been nice if they could accept a file containing the output of svnadmin dump instead…


Subverting Word Processors

I don’t think it’s unreasonable to want to store my documents in subversion. But what to do? Word processors all seem to produce ugly binary documents. Even though’s odt files are basically just zip files, it’s still putting zipfiles into your subversion repository.

Why is this a problem? Because you can’t see what’s changed. And if I make a change in two places, the tool can’t merge the changes for me. Not automatically and not without some hassle, anyway.

Having grappled with this a little bit over the last couple of weeks, I’m coming to the conclusion that the only safe format for storing files in is RTF. Thankfully, not only is it plain-text, but it’s also understood by the vast majority of word processors out there, including the lowly TextEdit and WordPad.



I’ve just found the svnmerge tool. It’s a real boon if you have to work with branches in subversion. It’s still not quite as simple to use as svk but it’s still better than doing things by hand…


New Releases

I’ve just done a couple of new releases of my modules:

  • JavaScript::JSLint 0.04, which is just renaming from Lint to JSLint to more accurately reflect where it’s come from (pointed out by Matthias Miller).
  • subatom 0.07 which switches from the baroque XML::Atom api to the much nicer XML::Atom::SimpleFeed (thanks, Aristotle).
  • subatom 0.08 because I am a doofus and left a warn statement in.

Typo Upgrade

I’ve finally bit the bullet and upgraded Typo to the trunk, so I can get everything up to Rails 1.1. Unfortunately, this was quite a painful process…

Normally, I track bits of software I might want to hack on in a vendor branch in subversion, and use to update to new releases. This works extremely well with wordpress at work, for instance.

Sadly, couldn’t cope with the typo trunk, as a directory got replaced by a symlink. Ooops. I tried working around it, but eventually, it was easier to give up and start afresh, redoing the changes I’d already made in subversion. I suppose it would have been a lot easier with SVK.

Unfortunately, a number of things haven’t caught up with the latest typo changes. In particular, the origami theme that I was using needs some loving attention. So it’s back to the default theme, “azure” for the moment, until I can spend some time on it.

Also, I couldn’t figure out how to make the google sitemaps patch work, so that’s another “gone for now” feature.

Please let me know if you spot anything else…

Update: Comments now enabled. Sorry about that.

Update#2: I’ve now fixed the comments feed a bit. It turns out that one of the migrations missed out on creating guids for all the comments…

  % ruby script/console production
  >> comments = Comment.find_all
  >> comments.reject { |c| c.guid }.each { |c| c.create_guid; }