Subversion For Writers

Introduction

This article was inspired by a question asked by a user on the WriteRoom Forum. This person was asking about facilities for working with multiple drafts of a work in progress; a process he was currently doing manually by saving his work with a new timestamp in the files’ names every time. What a lot of work! Clearly a job for a lazy geek to step in and show how it can be done easily!

I wrote this primarily with WriteRoom users on the Mac in mind, but very nearly all of what follows applies equally well to users of most other editors or wordprocessors, either on the Mac or on Linux or any other Unix. The concepts can also be used on Windows, but the step-by-step reality is likely to be quite different.

WriteRoom has no revision control facility integrated into itself; nor in fact do many of the text editors or word processors that exist, and the original answer to the question was, as WriteRoom is a Mac OS X application, to depend on Time Machine. While that would work, there are some problems with that; most pertinently, perhaps, that it doesn’t keep history forever; when the Time Machine volume is full, it will start deleting old backups.

However, this is a requirement that has been very comprehensively addressed elsewhere, primarily for software developers, who have a need for making ongoing revisions to work over time, and collaboratively. It’s called Revision Control, and the software that’s used to do it is a Revision Control System, and there’s absolutely no good reason why developers should have the benefits all to themselves.

What does it do? It manages multiple versions of a project in development. You check your project out of the repository, make changes and you commit those changes back to the repository. At any time you can view older versions of the whole project or of individual files, and revert to them, if the work done since was in error. You can make branches, which allows you to develop your work in two (or more) ways in parallel, and you can tag your project to say, at this point I met a certain milestone (eg: first draft, second draft, version sent to publisher X, version sent to publisher Y, published version, etc.)

There are many such revision control systems out there, from the venerable and pretty limited original actually called “Revision Control System”, or “RCS” for short, through many others with names like “CVS”, “Subversion”, “Bazaar”, “Git”, “Perforce”… The list goes on. Each one has its adherents and detractors, and I’m not even going to begin to address their arguments.

I’m just going to talk about setting up and using Subversion if you’re a writer. Why Subversion in particular? Simply because it’s the one I use. It is quite simple to set up and use and, perhaps more importantly, it’s already installed as standard on every copy of Mac OS X Leopard.

Installation

Mac OS X Leopard: Do nothing. You already have it. However, you may wish to install a GUI front end so you don’t have to do everything via the terminal. An example is SCPlugin, which integrates some Subversion operations with the Finder. I’ll come back to that later.

Older versions of Mac OS X: You’ll need to install it. The easiest way is to download and run a pre-built binary installer found here. Alternatively, you can build and install it from source yourself, but it’s a lot easier to first install either MacPorts or Fink and install it via that. Visit either site to find downloads and instructions.

Other Unix and Linux: Generally you’ll install it via your normal package management system. Just search for, and install, “subversion”. Again, there may be GUI front-end software available, such as the Subversion script collection for Nautilus, which fulfils a similar function to SCPlugin on the Mac by integrating subversion operations in the file manager.

Windows: (Not covered in this version. Probably “Install TortoiseSVN or RapidSVN” but I know no more.)

Setting up a new project

I’m going to demonstrate with this one. We’re going to do this the simplest way possible.

I’m going to start with the assumption that you’re keeping all the files relating to the project in one folder. That folder may contain other folders, but at the top there’s just the one. If that’s not the case, make it so now.

In the example of this article, I’m going to create a folder on my Desktop called “subversion-for-writers” and I’m going to save this text file into it as “Subversion For Writers.txt”. I can do all that from within WriteRoom just by pressing Command-S now…

Save file

You can hide the extension or not as you prefer; it’s not hidden to the command-line or to Subversion.

Now we’re going to create a new repository for this project.

Open a Terminal window. (Run Terminal, which can be found in your /Applications/Utilities folder, or by starting to type “terminal” into Spotlight.)

Enter the following commands. Substitute “subversion-for-writers” to the name of the folder containing your project.

This creates a folder in your Documents folder to contain all your Subversion repositories. You could as well create this using the Finder. In all these commandline examples, the command you enter is the part after the $ on the first line. That $ and the text to the left of it is the command prompt, and the subsequent lines are the output of the command (where there is any - a “feature” of Unix is that, often, if a command completes successfully there is no output at all; you just get the next command prompt).

rachel@pooka ~ $ mkdir Documents/repos

This creates a repository for the new project:

rachel@pooka ~ $ svnadmin create Documents/repos/subversion-for-writers

This moves us into your current project folder:

rachel@pooka ~ $ cd Desktop/subversion-for-writers

This imports everything in your current project folder into your new subversion repository:

rachel@pooka ~/Desktop/subversion-for-writers $ svn import file://$HOME/Documents/repos/subversion-for-writers --message "Initial import"
Adding         Subversion For Writers.txt

Committed revision 1.

That --message "Initial import is just a text message to remind you what you did. If you don’t include it on the command line, an editor will be launched for you to type a message in. By default, in Terminal, that editor is probably vim, which will be confusing if you don’t know it; so for now, use the --message "message" on the commandline.

You should now not make any further changes inside that project folder. Instead, put it in the Trash, or archive it somewhere. We’re going to check-out the project from Subversion and all future work is done there.

This just moves you back into the Desktop folder:

rachel@pooka ~/Desktop/subversion-for-writers $ cd ..

Now you can throw away or archive your existing project folder, which you can do from the Finder.

Now we’re going to check-out the project from Subversion. In your terminal window, type:

rachel@pooka ~/Desktop $ svn checkout file://$HOME/Documents/repos/subversion-for-writers
A    subversion-for-writers/Subversion For Writers.txt
Checked out revision 1.

And we’re done.

Committing changes

You can now continue editing the files in your project, and commit the changes. I’ll do so now, to commit the description above.

Save any currently unsaved files.

In your terminal window, type

rachel@pooka ~/Desktop $ cd subversion-for-writers

(That’s just the first time. Then you’re in.)

rachel@pooka ~/Desktop/subversion-for-writers $ svn commit -m "Added description of initial import and checkout and corrected some markdown errors"
Sending        Subversion For Writers.txt
Transmitting file data .
Committed revision 2.

Obviously you write a message that’s appropriate to what you’re doing.

Adding files

I’m going to add the screenshot I took earlier, when I first saved this file. So I load up the screenshot I took into Preview, crop it as I wish, and save it as “Picture 1.png” inside my subversion-for-writers folder.

In your terminal window, type something similar to:

rachel@pooka ~/Desktop/subversion-for-writers $ svn add Picture\ 1.png 
A  (bin)  Picture 1.png

The (bin) is just a note from Subversion that it’s recognised that image file as a binary, as opposed to a text file. Note (and this is important); the file is not actually added to the repository until you commit.

So let’s edit my document to include a link to it, and some description, and a couple of fixes, and commit:

rachel@pooka ~/Desktop/subversion-for-writers $ svn commit -m "Added picture 1"
Adding  (bin)  Picture 1.png
Sending        Subversion For Writers.txt
Transmitting file data ..
Committed revision 3.

By now you’ll have noticed that each time you commit, the revision number goes up by 1. We just committed revision 3.

Seeing the difference between revisions

You can, for instance, see the differences between any two revisions using the svn diff command, like so:

rachel@pooka ~/Desktop/subversion-for-writers $ svn diff -r 2:3 Subversion\ For\ Writers.txt 
Index: Subversion For Writers.txt
===================================================================
--- Subversion For Writers.txt  (revision 2)
+++ Subversion For Writers.txt  (revision 3)
@@ -38,7 +38,7 @@

 In the example of this article, I'm going to create a folder on my Desktop called "subversion-for-writers" and I'm going to save this text file into it as "Subversion For Writers.txt". I can do all that from within WriteRoom just by pressing Command-S now...

-<Picture 1>
+<img src="Picture 1.png" alt="Save file"/>

 You can hide the extension or not as you prefer; it's not hidden to the command-line or to Subversion.

@@ -62,12 +62,12 @@

 This imports everything in your current project folder into your new subversion repository:

-   rachel@pooka ~/Desktop/subversion-for-writers $ svn import file://$HOME/Documents/repos/subversion-for-writers -m "Initial import"
+   rachel@pooka ~/Desktop/subversion-for-writers $ svn import file://$HOME/Documents/repos/subversion-for-writers --message "Initial import"
    Adding         Subversion For Writers.txt

    Committed revision 1.

-That `-m "Initial import` is just a text message to remind you. If you don't include it on the command line, an editor will be launched for you to type a message in. As, by default in Terminal, that editor is probably `vim`, which, if you don't know it, will be confusing; so for now, use the `-m "message"` on the commandline.
+That `--message "Initial import` is just a text message to remind you what you did. If you don't include it on the command line, an editor will be launched for you to type a message in. As, by default in Terminal, that editor is probably `vim`, which, if you don't know it, will be confusing; so for now, use the `--message "message"` on the commandline.

 You should now not make any further changes inside that project folder. Instead, put it in the Trash, or archive it somewhere. We're going to *check-out* the project from Subversion and all future work is done there.

@@ -85,6 +85,9 @@

 And we're done.

+Committing changes
+------------------
+
 You can now continue editing the files in your project, and commit the changes. I'll do so now, to commit the description above.

 Save any currently unsaved files.
@@ -95,3 +98,24 @@

 (That's just the first time. Then you're in.)

+   rachel@pooka ~/Desktop/subversion-for-writers $ svn commit -m "Added description of initial import and checkout and corrected some markdown errors"
+   Sending        Subversion For Writers.txt
+   Transmitting file data .
+   Committed revision 2.
+
+Obviously you write a message that's appropriate to what _you're_ doing.
+
+Adding files
+------------
+
+I'm going to add the screenshot I took earlier, when I first saved this file. So I load up the screenshot I took into Preview, crop it as I wish, and save it as "Picture 1.png" inside my `subversion-for-writers` folder.
+
+In your terminal window, type something similar to:
+
+   rachel@pooka ~/Desktop/subversion-for-writers $ svn add Picture\ 1.png 
+   A  (bin)  Picture 1.png
+
+The (bin) is just a note from Subversion that it's recognised that image file as a binary, as opposed to a text file.
+
+... And edit my text to include it, and commit:
+

As you can see, the format is a bit technical, but essentially it shows the lines that changed from the first revision number given to the second, which is useful if you want to be able to check what you did.

The lines that start with - are those that were in revision 2, but not in 3, and the lines that start with + are the lines that are in revision 3, that weren’t in 2. A few lines above and below the ones that have changed are included for context.

Other important commands

Some of the other commands you’ll want are:

SCPlugin

All the above holds true not just for Mac OS X, but also for subversion on any unix/linux platform and probably Windows too if you have the command-line client installed. For day-to-day work, however, you might prefer to install SCPlugin, which integrates many of the above operations into the Finder, but not all of them.

You’ll still have to do the initial setup as described above from the commandline; that’s:

In addition, SCPlugin can’t do renaming or moving of files, so if you need to do that you still need a terminal open to do

Most of the rest you can do in SCPlugin.

To demonstrate with a second checked-out copy of this project:

SCPlugin checkout 1

SCPlugin checkout 2

SCPlugin checkout 3

Then we make some changes (these ones!):

Making changes!

Add the new files…

SCPlugin add files 1

SCPlugin add files 2

And commit our changes:

SCPlugin commit 1

SCPlugin commit 2

SCPlugin commit 3

And we’re done.

Notice the little marks on the file icons of files under Subversion control? That’s an SCPlugin thing. If we turn off icon previews we can see them on the files themselves:

SCPlugin icons

After it’s been added:

After it's been added

The folder, with two files added, one not yet added, and the main article file has been edited. We need to commit.

SCPlugin two added, one changed, one unknown

SCPlugin commit 4

It’s good to be green:

SCPlugin Good to be green

As you can also see, I got bored of making the picture files’ extensions visible in the finder. It makes no difference to Subversion.

RapidSVN

RapidSVN is another Subversion GUI application, which has the added advantage of being multi-platform; it exists already for Mac OS X, Windows and Linux/Unix generally (in X11). I haven’t used it myself (preferring SCPlugin and comfortable to escalate to a commandline when necessary), but it is probably worth a look if you’d rather do everything from a nice windowed application.

I may update this section with a mini-tutorial later. Or someone else could!

’Tis but a scratch, my liege!

We’ve barely scratched the surface of Subversion. I just wanted to quickly demonstrate how to set up a simple project and work with it. A get-you-started for writers rather than software developers.

The best place to learn more about Subversion is the Subversion Book which will, among other things, quickly tell you that I told you to do the initial project import wrongly. There’s no provision for branching, merging and tagging. But that’s actually repairable, should you need those features. It also shows how you can set it up as a network-accessible svn server, so you can check out and commit from multiple machines - or indeed work collaboratively with other people on the same project. What we’ve done here is very simple but it does mean that only you can work on that project, and only on the one machine.

You can use all this method with wordprocessors with binary file formats (eg: MS Word, OpenOffice.org); but you lose some of the benefits. When storing text files, Subversion generally only stores the complete file in the initial version, and from then on stores the differences from one version to the next. (That may be simplistic, but it’s a working assumption.) It can’t do that for binary files; so the repository gets a lot bigger, as each change that’s committed means a complete new copy of the file is stored, and certain analytical methods, like svn diff won’t work.

RTF, HTML, XML, et al, are basically text files with markup, and as such work well in Subversion.

Applications which really aren’t suitable include any that maintain the contained files in a project itself, invisibly adding and removing files while you work. Examples of these include Ulysses and Scrivener (both of which I bought and used for a while before ending up doing what I’m doing now), which store a project as a Mac OS X bundle, and individual files as RTF or RTFD, managing the internal content of the bundle by themselves. You could use this with Subversion but it would be a lot of work as you’d have to manually add and remove those auto-created, auto-deleted files inside the bundle yourself. It’s basically not worth the hassle. If the authors of those applications want to, they can integrate revision control in the applications themselves - either completely embedded (as with Word/OpenOffice.org) or making use of external repositories like Subversion. The application knows when it creates, renames and deletes files, so it would be the place to integrate a subversion client. It could work well that way, and for all I know, they might even have added a facility like that since the last time I looked at them.

Production Notes

As you can see from the screenshots, for this particular mini-project I quickly switched from WriteRoom to TextMate, as an editor more suitable for the project in hand. This is basically because I’d decided to write a HTML page with images, but for convenience I wanted to actually write in plaintext and get MultiMarkdown to do the legwork of turning it all into nicely-formed HTML, and TextMate has good Markdown/MultiMarkdown support, as has been occasionally snapped in the screenshots.

I do the same thing when writing stories (when I get a round tuit); writing in plaintext with markdown syntax. It’s a nice way to work in a clean, distraction-free way (that, sans syntax colouring, works well in WriteRoom) and yet provide good quality HTML output at the end. As the demands that prose text makes on formatting are so much lighter, it’s perfectly comfortable to use in WriteRoom. This particular mini-project just got complex enough that TextMate’s conveniences became sufficiently desireable to switch. (Not least because I was switching a lot between the text editor, the Finder, and a Terminal window, at which point an application that keeps popping into a full-screen mode gets tiresome!)

One of the nice things about working this way is that it is truly platform and software independent. If you like TextMate now, but want to switch your project to WriteRoom, or even if you’re switching back to Windows (you pervert!) and going to use DarkRoom or NotePad even, or to Linux or any other Unix either at the commandline or in a desktop environment, your project goes with you with the minimum of fuss. So many writing solutions trap you in a specific application.

In fact, for my usual work, my private writing subversion repository resides on one of my Linux machines in a webserver, and I can (and do) check out, update and work on my stuff from any of my machines, whether they be Macs or Linux boxes or even my phone.