SVN

Subversion or SVN, like CVS, is a system which allows you to track and roll back changes on text files. This is very useful for the source of documents or code. It also allows multiple developers to work on a project.

Here are my SVN notes corresponding to my earlier CVS notes. Everything else should be answered by a look at the manual.

The SVN manual is rather fat and daunting. But worthwhile a proper read in the long run. If you are new to this sort of tool, at least skim it. Unless you are administering a big shared repository you might be best to just start a new project as below. You can learn the rest as and when you need it.

Create a personal repository

svnadmin create "$HOME/SVN_repository"

Starting a new project

mkdir tmpdir
cd tmpdir
mkdir project_name/{,trunk,branches,tags}
svn import . "file://$HOME/SVN_repository" --message 'Started project [name]'
cd ..
rm -r tmpdir

To get a working copy of the project do:

svn checkout "file://$HOME/SVN_repository/project_name/trunk" project_name

and then every so often tell the repository about your changes:

svn commit

in the directory containing the working copy of your project. When you create new files you’ll need to “svn add” them. Don’t add files that can be exactly and automatically reproduced from other source files.

If you have more than one working copy on the go (e.g. when working with other people) do

svn update

to get their changes (and sort out any resulting conflicts) before committing. You may have to “svn update” every so often anyway, to convince SVN it is safe to remove files “svn delete” or to display the logs you expect it to.

Tags and branches

You can already request SVN gives you all the files at a particular revision number or at a particular time. If you prefer to give a friendly name to a revision, just take a copy (snapshot) of your whole project:

svn copy "file://$HOME/SVN_repository/project_name/trunk" \
         "file://$HOME/SVN_repository/project_name/tags/release-1.0"

This “copy” does not actually take up any extra space in the repository (except the log information).

Branches are exactly the same:

svn copy "file://$HOME/SVN_repository/project_name/trunk" \
         "file://$HOME/SVN_repository/project_name/branches/my-experimental-branch"

Except it is expected (by convention only) that copies in branches/ will change and those in tags/ will not.

You probably don’t want to check out "file://$HOME/SVN_repository/project_name" as this will give you lots of copies for all branches and tags. You can do

svn list "file://$HOME/SVN_repository/project_name/tags"

if you just want a listing of what tags are currently defined in HEAD.

Remote usage

If you have ssh access to a machine you can remotely access a repository by replacing file:// with svn+ssh://<hostname> (with no additional setup). SVN will also work over https:// (although that requires a special svn apache set up).

Keyword expansion

To make $Id$ automatically expand into current version information (useful so that code can put its version into its output log) do:

svn propset svn:keywords 'Id' *.c{,pp} *.h Makefile

(or match whatever files are appropriate). 'Id HeadURL' might be useful, especially if using a public repository: $HeadURL$ will tell people where they can go to get other versions of the files.

Ignoring files

If svn status output is cluttered with '?' entries then use:

svn propedit svn:ignore .

Your $EDITOR will pop up and you can specify a newline-separated list of (wildcard) filenames. Use svn status --no-ignore to still see ignored files.