mikeash.com: just this guy, you know?

Posted at 2008-02-09 21:31 | RSS feed (Full text feed) | Blog Index
Next article: Goodbye, Nibs
Previous article: Performance Comparisons of Common Operations, Leopard Edition
Tags: python subversion utility versioncontrol
A Tool for Editing Version-Controlled Bundles
by Mike Ash  

If you're like me, you sometimes have to edit rtfd files which are under version control, and it's painful. TextEdit and Xcode will blow away the version control directory (if you use the sort of version control which keeps directories in everything) and it's annoying to work around it. I finally got fed up enough to write a script which works around it for me.

Download the script here. Rename it to bundleedit.py and put it somewhere in your $PATH.

The script assumes you use subversion, but can be changed to something else by editing the versionControlDir variable. If you're a CVS user, change it to 'CVS'. If you use something else, hopefully you'll know what to change it to.

Usage is easy. Feed it the path of one or more bundle-style documents which are under version control. It will open them one by one in the default editor for that file type. Make your changes and then quit the editor, and you're done. If you specified more than one file it will re-open the editor for the next one, repeating until you've edited them all.

The concept of the script is very simple. It simply moves the .svn directory to a temporary location, then opens the bundle. When you're done editing, it moves the .svn directory back to its original location. End result: you get a modified document that's still under version control.

It takes advantage of two useful flags to the /usr/bin/open command. The -W flag makes it wait until the editor quits before continuing so that it knows when to replace the version control directory. The -n flag makes it always open a new instance of the editor even if it's already running. This ensures that you can quit it without disturbing any documents you already had open.

This script is intended to work with rtfd files because that's the only bundle type I use which isn't version control friendly, but it should work with any other unfriendly bundle type you might have as long as open works with it.

Did you enjoy this article? I'm selling whole books full of them! Volumes II and III are now out! They're available as ePub, PDF, print, and on iBooks and Kindle. Click here for more information.


Pages and Numbers do the same thing. I filed a bug about it.

Do you think this is intentional or a side effect of the API they are using? I'm guess they are using one of the write atomically API's and that when the directory is copied to its actual local the .svn directory is blown away.
I believe it's just a side effect of the NSDocument system. I believe the apps get an NSFileWrapper, read the pertinent information, create a new NSFileWrapper with the file's information, and write that back out. They create a new directory with the new contents, rather than reusing the old. Given all this, if they don't explicitly preserve version control directories, they'll disappear. Interface Builder does this correctly but, I believe, only because it does explicitly preserve them.

It would be interesting to write an Input Manager or something like that which would patch NSDocument to fix this system-wide, but I preferred to be a little less ambitious.
This was one of themes we've been playing with at CocoaDevHouseMunich06. We wrote an input manager, that swizzles some method[s] in NSDocument, and moves .svn subdirectories out and back when writing of document is performed.

Neat concept, but if I'm going to be using the command line anyway, I think I'd rather just use a version control system that hasn't been ignoring this problem for so long. Is there some deep magical versiony stuff Subversion can do that some developers need?

Both Bazaar or Mercurial have what I know enough to want in a version control system, and the only thing I'm waiting for is Xcode SCM plugin support. Whereas with SVN, I'd be waiting for the bundle issue to finally get fixed, and then waiting for offline commits to maybe eventually get tacked on, and then for Xcode to catch up anyway...
Why does anybody use any system that isn't perfect? Because none of them are.

I use subversion because it's familiar, it gets the job done, and it's what everyone else in the company uses.

Offline commits do not concern me. The bundle issue is really a bug with the apps, and only bites me with rtfd files (and obviously the fix is not that hard). Xcode's SCM integration is worthless so that's irrelevant anyway.

Comments RSS feed for this page

Add your thoughts, post a comment:

Spam and off-topic posts will be deleted without notice. Culprits may be publicly humiliated at my sole discretion.

The Answer to the Ultimate Question of Life, the Universe, and Everything?
Formatting: <i> <b> <blockquote> <code>.
NOTE: Due to an increase in spam, URLs are forbidden! Please provide search terms or fragment your URLs so they don't look like URLs.
Hosted at DigitalOcean.