Navigation: content | home | news | plan | contact | material | links | project | svntips
Tips on using SubversionThis page has some tips on using Subversion for version control for the 371 project. Now updated for 2008.
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:
Subversion uses a versioned virtual filesystem backend, stored inside a database, for its repository (unlike CVS, which uses real filesystem directories containing RCS history files). This means that:
Subversion better handles file operations like delete, copy, rename (which CVS doesn't have at all), and creating directories. These are just versioned operations on the virtual filesystem. In particular copying in the repository is a very cheap operation: Until you make changes to the copy (which like other changes are stored as diffs), the copy takes up virtually no space — it's essentially just a note that this file (or directory) is a copy of some other.
In Subversion, version numbers apply to the whole repository, not to individual files, as they do in CVS. You might do an update in your checked-out directory, find that the revision number has increased but that none of your files have been changed. This is because checkins in some other directory of the repository have changed the revision number of the whole repository, while not affecting your files. This is a bit unsettling at first, but you get used to it, and (when you think about it) it actually makes more sense.
Subversion doesn't have branching and tagging like CVS, since pretty much all the effects of branching and tagging can be achieved more elegantly just by creating new directories in the repository which are virtual copies of the main trunk at some point in time. It's feasible to use copying for branching and tagging because making copies in the repository is a cheap operation. You could call these copies whatever you like, but there are some naming conventions generally used in Subversion to make it clearer which is which.
Subversion better handles binary files, both in doing clever binary diffs for new versions of binary files, and in guessing what kind of file it is you're checking in (although sometimes it needs help).
Subversion keeps more information around than CVS, in the
.svn subdirectory of each working directory (for
example it keeps squirreled away complete copies of all the
sources as they were last checked-out or updated). This means
that many useful svn operations can be performed
without reference to the repository, such as simple diffs and
status queries. This is a big advantage when working remotely,
since you can get a fair amount of useful work done while
off-line, without a network connection.
Subversion allows you to associate arbitrary metadata with a file via properties. You can do a lot with this. Most commonly used are probably the two built-in properties:
svn:executable
is used to tag a file as executable — useful if you're checking-in from a filesystem that doesn't support such a notion, but need to record that information in the repository.
svn:ignore
provides a list of file names or file globbing patterns, which
are to be ignored in the directory to which this property is
attached. The main use of this is so that status listings and
adds and imports won't get cluttered with editor backup files
and compilation products, etc. The default built-in ignore list
covers common cases like Emacs's *~ backup files
and .o object files, but doesn't know about say
Java .class files.
Subversion mostly uses a URL-style syntax for specifying
repository locations: file: for a repository in the
filesystem, svn+ssh: for accessing a remote
repository securely using ssh (simplest to set up
for remote access), and http: and
https: for accessing a repository via a suitably
configured Apache webserver. Note that the Subversion client
svn has built-in support for ssh and
doesn't have to use an external ssh (or
rsh) program like CVS does.
In the instructions below, keep the following in mind:
In a URL, host means one of the CSSE
student machines, like cat or queeg.
Several svn commands, in particular
import and commit (or
ci), will crank up your favorite editor (as
specified by your EDITOR environment variable) for
you to enter the commit message. You can head this off by using
the -m (or --message) option to
specify the commit message on the command line.
If you use the remote svn+ssh URL (or indeed
ssh directly), you'll be prompted for your CSSE
password unless you've set up the private/public key pairs for
ssh. This also assume that your remote username is
the same as your CSSE username. If it's different, you'll need
to specify your CSSE username. Consult the ssh and
Subversion documentation for details.
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.
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:
It's important to follow this naming convention for the repository, to simplify processing for the marking.
Your repository is in a subdirectory under your group directory, not in your group directory itself. There's a reason for this: so you can put other team-sharable files under your group directory, without their being in the repository.
In Subversion, repository maintenance is done by a special
command svnadmin, and can be done only through the
filesystem via a filesystem path, not remotely via a URL.
Subversion can store its virtual filesystem in two different
database formats. The fsfs format is the newer, is
generally better, and is now the default — but no harm
being explicit.
The umask 007 setting is the easiest way to
set up the repository so all team members have the correct
permissions. Be sure to change it back to the more paranoid
umask 077 setting; otherwise all other
students will be able to read and write your files created under
your normal group student. You shouldn't have to
worry about umask from here on: pretty much all the
Subversion commands will operate on the database file, for which
permissions are now set properly.
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.
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.
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.
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.
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.
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:
diffto list differences between working files and their repository version (plus many other variations).
logto show the log messages.
cp/rm/mv/mkdirto (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).
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.
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.
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).
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