CARVIEW |
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…
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:
svn update
This is the command used to update your working copy with the latest version from the repository. It’s more relevant when you’re working on more than one machine, or when there are more than one of you working on the project. For either case you’ll have needed to do a more complex initial setup than we did here.
If you include the
--revision
parameter, eg:svn update --revision 4
, you can revert to an earlier version of your entire project, or just of individual files.svn remove <name>
Removes a file that was previously added. You should use this to delete a file you no longer want in your project, rather than just deleting it directly or putting it into the Trash in the normal way.
svn rename <old-name> <new-name>
Renames a file. Again, if you want to rename a file in your project, do it this way instead of directly in the Finder. If you just do it in the Finder, Subversion doesn’t know it’s happened.
svn move <old-path> <new-path>
Moves a file from one location to another. (In fact, rename and move do exactly the same thing.)
svn mkdir <name>
This creates a subfolder inside your project, in a way that, again, Subversion knows about it. You can instead just create a new folder in the Finder, but you’ll need to use
svn add <folder-name>
afterwards.svn log <name>
This gives a list of all the changes made on a given file. For instance:
rachel@pooka ~/Desktop/subversion-for-writers $ svn log Subversion\ For\ Writers.txt ------------------------------------------------------------------------ r3 | rachel | 2008-04-17 17:38:40 +0100 (Thu, 17 Apr 2008) | 1 line Added picture 1 ------------------------------------------------------------------------ r2 | rachel | 2008-04-17 17:24:43 +0100 (Thu, 17 Apr 2008) | 1 line Added description of initial import and checkout and corrected some markdown errors ------------------------------------------------------------------------ r1 | rachel | 2008-04-17 16:41:08 +0100 (Thu, 17 Apr 2008) | 1 line Initial import ------------------------------------------------------------------------
As you can see it lists each revision, backwards from the current one, with the time and date and message.
svn diff <name>
With no -r parameter, this shows the differences in a file since the last time you committed it (ie: what you’ve done so far in this session).
svn revert
Discard all the changes you’ve been making since the last commit. You must have been on crack or something. Note that if you’ve earlier removed (
svn remove
) any subfolders, they won’t be restored. A subsequentsvn update
should do that.svn help
To tell you how to use it.
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:
svnadmin create
svn import
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
svn move
svn rename
Most of the rest you can do in SCPlugin.
To demonstrate with a second checked-out copy of this project:
Then we make some changes (these ones!):
Add the new files…
And commit our changes:
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:
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.
It’s 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.