Subversion Reversion: “Icon\r” Boom Unrepeatable?

Uli, in the comments for my last post, said “Might be a good idea to report this as a bug in SVN so they can fix it.”

Sentiments like that can only end in tears, I tell ya!

There’s already a Subversion bug covering one part of the behavior I saw, 1830: Dump format does not handle newlines in filenames.

In the comments for that bug, the developers seem to have come to the conclusion that they would fix the problem by disallowing files with newlines.

And they seem to have succeeded! In trying to reproduce the bug, I found that I could not add an “Icon\r” file to a repository either by import or by add. In both cases, I got the error message: Invalid control character '0x0d' in path 'xxx/Icon

Now, I know I never added the “Icon\r” files explicitly myself. I thought I might have done it in the initial import, but the tests I ran above say no.

Although…this could be a difference between the Subversion 1.1.4 package (or maybe even earlier) I originally used and the Subversion 1.2.0rc4 package I upgraded to when trying to investigate the problem.

That seems like the most probable, not to mention hopeful, explanation, so I’m going to leave it at that.

Note: With this post, I have used four words from RhymeZone that rhyme with “subversion,” out of a total of twelve. Eight to go!

I’m now also using subtitles, so the post names are at least somewhat comprehensible. And no, your memory isn’t playing tricks: I retroactively added subtitles to the first two Subversion posts.

Subversion Diversion: “Icon\r” Files Make Repository Go Boom

When I got back to my personal project recently and tried to commit some files to its Subversion repository, I started getting an Abort Trap error message. At this point, I was told by Subversion that I needed to use svn cleanup in the local copy and svnadmin recover /My/Repository on the repository to make things right.

I couldn’t find anything online about other people having these problems.

So I decided, if the repository was bad, I would dump and reload it, and maybe that would fix the problem. I used the Subversion commands I described in this previous post to do it.

What I discovered was that the reload process halted at an “Icon” file. Actually, the name of the original file was not “Icon”, but rather “Icon\r”, where the “\r” indicated a carriage return a.k.a. ASCII value 13 character, which is the old Macintosh linebreak character.

As described at on this page (but curiously, nowhere that I could find on Apple’s ADC Web site), “Icon\r” files are the way to specify that the enclosing folder should have a custom icon, and to specify what that custom icon should be. Such files are invisible due to a particular bit set in their HFS information. Update: in the original version of this post, I said they were just the OS 9 way of doing this, but I was wrong; OS X still uses this technique for everything except volume icons. (Thanks, Uli!)

In any case, they must have been sucked into the Subversion repository I made. If I used my original repository dump file, I could even make the “Icon\r” files show up in the Finder, since the hidden bit is not preserved by Subversion. But any attempt now to commit any changes while these “Icon\r” files existed made my repository go boom. (Why didn’t this show up during earlier commits? Dunno that, either.) This included any attempt to delete those “Icon\r” files. I was stymied.

However, there was a way to modify the dump file I had been able to make (though not re-load). Subversion dump files are human-readable text files, but the file I had was 80 Mb., basically unreadable in any text editor on my machine without a lot more RAM. Luckily, the Subversion authors saw just this possibility, and made a utility, svndumpfilter, that can be used to filter specific files out of a dump file.

This quote from the Version Control with Subversion manual explains:

Simply give it either a list of paths you wish to keep, or a list of paths you wish to not keep, then pipe your repository dump data through this filter. The result will be a modified stream of dump data that contains only the versioned paths you (explicitly or implicitly) requested.

See the rest of the manual for more details: it’s quite nicely written.

Using that utility, I was able to remove the “Icon\r” files completely from my dump file (as if they had never existed), load the repository in again, and go from there, with no loss of history for the files I hadn’t removed.

One nice thing was that once I’d removed the “Icon\r” files from the trunk area of my repository, they were also gone from the one tag area I’d made. I didn’t have to manually remove the files from both places.

Updated: made corrections suggested by Uli in the comments.