Navigation: content | home | news | plan | contact | material | links | project | svntips

Tips on using Subversion

This page has some tips on using Subversion for version control for the 371 project. Now updated for 2008.

Subversion for version control (2008 version)

Most of you should have had some previous experience with using CVS, if only in 252. For most common usages Subversion works in almost the same way as CVS, but it is in most respects better than CVS, and its repository philosophy is quite different. In any case, here are some tips on using Subversion, which you might find useful. Also here are some requirements about how your repository should be set up. This is to ensure that all repositories are set up in the same way, to expedite the marking process.

First thing to remember is that while Subversion is a very rich system with lots of options, for most usage it's very simple.

Like CVS (and unlike RCS), Subversion uses a command-subcommand structure. So you invoke, say, the Subversion client svn and give as the first argument the subcommand for the operation you want it to perform.

Probably, the main differences from CVS you'll notice are the following:

In the instructions below, keep the following in mind:

A Simple Subversion Recipe

There are lots of ways to set up and use Subversion. Here's a simple recipe you can use. If you know what you're doing, you can take short cuts and make refinements (so long as the resulting repository structure ends up the same). But here I concentrate on simplicity. Following something like this recipe should give you a structure to work within.

  1. Note, only one member of the team should perform this step and the next step on behalf of the team, since they set up the shared repository. Create your Subversion repository, by

    umask 007
    svnadmin create --fs-type fsfs /home/studproj/371/groups/s371gXX/repo
    umask 077

    where s371gXX is your team's assigned group.

    Then, just to be sure, run

    ls -lR /home/studproj/371/groups/s371gXX/repo | less

    to check that repository has been set up properly. Basically all the files and directories should be in your team group, the group permissions should be the same as the owner permissions, and world (other) permissions should be empty. This will also give you a glimpse into how a Subversion repository is structured. The meat of it is the file that contains the virtual-filesystem database, but there are a bunch of other auxiliary files and directories. For the most part, you can treat the repository as a black box. However, you might find it helpful to exploit some of the hooks (see below).

    Points to note:

  2. Now, cd to an empty directory somewhere. Just make a temporary directory if need be. Inside that directory run

    svn import file:///home/studproj/371/groups/s371gXX/repo/trunk/diary

    Alternatively, you could remotely run

    svn import svn+ssh://host.csse.unimelb.edu.au/home/studproj/371/groups/s371gXX/repo/trunk/diary

    since svn import is a client operation, and can be done remotely.

    This step creates a virtual directory in the repository called trunk/diary, and imports into it all the files from the current directory. In this case the current directory is empty, so the repository directory is just initialized as empty too.

    Another way of doing this is to use the svn mkdir command twice with a suitable repository URL to create these two levels of directory directly inside the repository. This takes two commands, since (unlike svn import) svn mkdir will create only one level of directory each time (in this it is like Unix mkdir without the -p option), but avoids the need to make a temporary empty directory.

  3. This step should be performed by each member of the team. In a directory just above where you want your working directory to be, run

    svn checkout file:///home/studproj/371/groups/s371gXX/repo/trunk/diary

    Alternatively, from a remote machine you can run

    svn checkout svn+ssh://host.csse.unimelb.edu.au/home/studproj/371/groups/s371gXX/repo/trunk/diary

    This will create a subdirectory called diary, which will be your working directory of checked-out sources. To start with, so long as none of your other team members have checked-in any files, this working directory will be empty of source files, but it will contain the necessary Subversion administrative files, stored in a subdirectory called .svn.

    Notice that diary is not at the top level of the repository, but under a directory trunk. This is to fit with the common Subversion convention that the top level of a repository has three directories called trunk, branches and tags. The idea is that under trunk is stored the main trunk of development for all the components of the project (each in its own subdirectory), while branches and tags are used to store (virtual) copies used to achieve the effect of branches and tags in CVS.

From here on, just about everything you do will be inside your working directory diary, and because Subversion records information about where the working directory came from, you won't ever need, in normal use, to specify the repository again.

Using Subversion

  1. As you create source files, tell Subversion about them by running

    svn add file...

    Subversion is pretty good at figuring out automagically which files are text files (like program source and HTML), and which files are binary (like icon images). Rarely, it gets this wrong, and may need some help — but that isn't covered here.

  2. Run

    svn status

    to find out the status of your working directory. There's a lot more to it, but basically the plain command gives you a terse summary of your working directory: The letters M, A, D respectively indicate a file that's been modified, added or deleted in the working directory, but not yet committed to the repository. A question mark indicates a file that Subversion doesn't know about. This often means a file that you've forgotten to add, but may be a file produced by a program, like an editor temporary file, or (more likely) a .class file from a Java compilation (if you're building inside your working directory, as is often the case and will be the expected setup for this project).

    Notice that to reduce clutter, plain svn status doesn't mention at all files that are unchanged, since they aren't interesting. You can reduce clutter further by telling Subversion to ignore certain files or types of files, using the svn:ignore property on the directory. See the Subversion Book for details.

  3. At any time (but especially after a break or just before a commit), bring your working directory up to date with respect to the repository (including changes checked in by your team-mates) by running

    svn update

    Usually changes by other team members will be merged in with yours automatically. But (as with CVS) there will sometimes be conflicts (like when both you and another team member have made changes to the same lines of code), and these will have to be resolved by hand. Read the Subversion Book for details. The process of resolving conflicts is a little more structured in Subversion than it is in CVS.

  4. When you're happy with a set of changes, run

    svn commit

    or

    svn ci

    (for checkin) to commit your changes to the repository, both added (and removed) files, and (more usually) modified files.

    If another team member has already done a commit since your last update, then Subversion won't let you commit, and you'll have to run svn update to merge in the changes in the repository with your changes, so you can then commit versions which incorporate all changes.

Other useful svn subcommands are:

diff

to list differences between working files and their repository version (plus many other variations).

log

to show the log messages.

cp/rm/mv/mkdir

to (respectively) copy, remove, or rename a file (or directory), or make a sub-directory in the working directory (and affect the repository on the next commit). These subcommands have a number of convenient synonyms.

Note, if you want to perform such operations on your working directory, you must use these svn subcommands, not the normal Unix (or, for that matter, file-manager) operations; otherwise Subversion won't know about the changes. These operate differently from in CVS, thanks to the virtual file-system backend. For example, if you want to make copy of a file under CVS, you first have to make an ordinary copy in the working directory, then add this new file (before committing). CVS knows nothing about the connection between the two files, as far as it's concerned, the new file is completely unrelated to the file it's a copy of. In contrast, with Subversion, you use svn cp, which makes a copy in the working directory, and then later in the repository at the next commit. What's more, Subversion knows about the copy, that the new file is a copy of the old. Also, in the repository, this copy can be done quite cheaply as a virtual copy. Similarly for renaming (which is more common, but more complicated under CVS).

Remark

You can do a svn import in a directory already populated with your initial set of source files (if you've been coding before the repository was set up). But after you've imported from a directory, you normally should get rid of that directory and its files, to save confusion. For example, you might by accident start making changes in this original import directory rather than in the proper checked-out Subversion working directory. To be safe, you should remove the import directory only after you've done a successful checkout and verified, say by recursive diff, that the checked-out sources match those imported.

Also, if you import from an already populated directory, you should make sure there are no product files there, like Java .class files and editor backup files. Subversion will put them into the repository as well, where they'll stay forever, wasting space. (And, unless you subsequently set svn:ignore properly, any changes to these files, say by recompilation, will also be forever committed and tracked in the repository.) Remember that even if you remove a file, Subversion keeps a copy of it in the repository, in case you ever want to revert to a revision in which that file existed. There are ways around this — you can set global ignores before you do the import, or you can later use svndump to dump an editable dump of the repository, from which you can edit out all mention of the wrongly committed files. But such contortions are better avoided. In all, the simple recipe recommended here, of importing an empty directory, is least fuss.

Beware

Keep straight the distinction between those subcommands that generally operate inside a checked-out working directory (these are in the majority, like add, update, commit), and those that can operate outside the working directory (typically one level above), most notably checkout. If you say do an update above the working directory, then it will fail, because Subversion won't be able to find its admin files, which are in the .svn subdirectory of the working directory. If you say try to do a checkout inside the working directory then it will create another working directory below the current one.

As with CVS, your working directory and the repository should be completely separate directories. Weird things can happen if one of them happened to be a subdirectory of the other. This is largely because Subversion operates recursively (by default). Think about it... This is different from RCS, where the repository is usually in the RCS subdirectory of the working directory.

One common mistake is to create a file but forget to svn add it. The file is there in your sources directory, so you can use it, but Subversion knows nothing about it, and it isn't in the repository. Such files will be marked with a question mark when you do svn status, but this may be overlooked if there's a lot of clutter from un-ignored files.

Forgetting to add a file is more likely to be a problem for a solo project. It's less likely to be a problem for a team project: If you forget to add and commit a file, then your team-mates won't be able to check it out, and will probably notice its absence. But just be aware of this potential problem. Sometimes it's a good idea from time to time to do a separate fresh check-out from the repository, to make sure that nothing has been forgotten and that the whole system builds as expected from a fresh check-out.

Other Useful Stuff

TortoiseSVN is a GUI wrapper around Subversion that works under Windows. Most decent IDEs, like Eclipse or XCode, should have built-in support for Subversion.

Subversion provides a number of hooks, implemented as programs (probably scripts) that are run when certain things happen. You can, for example, create a hook that sends mail to all team members whenever anybody does a commit. These hooks live in the hooks directory of the repository, which comes pre-populated with templates (which you can look at to get ideas about how hooks work).

Finding Out More

The Subversion client svn has a built-in help facility, accessed initially via svn help. Similarly for svnadmin.

The main website for Subversion is http://subversion.tigris.org.

The definitive documentation for Subversion is the Subversion Book.

After that, you could post queries to cs.371. Now use the wiki Q&A.


The 433-371 subject pages are maintained by Les Kitchen. Post any enquiries, comments, corrections, or suggestions concerning these web pages to the wiki Q&A.

Generated on 16 September 2008.

Navigation: content | home | news | plan | contact | material | links | project | svntips