home | tech | misc | code | bookmarks (broken) | contact | README

# SVN notes

## SVN client howto

Important

When doing operations on the repository with the svn command, it is necessary to specify the full repository path. For example, supposing that the server is serving svn using ssh. To checkout a directory of a project, do (like described here):

$svn checkout svn+ssh://hostname/path/to/repository/project/trunk  It will make login like logging in a machine through ssh. ### Accessing the repository through ssh This requires a Unix account on the SVN server. After setting up a SVN repository as told in SVN Server Setup, it will be necessary to create individual directories for the projects: $ svn mkdir svn+ssh://hostname/path/to/repository/project


As told here, it is convention for subversion users to create some directories below the project root:

trunk/              - main flow of development
branches/           - any branches of development
tags/               - snapshots of the repository


So:

$svn mkdir svn+ssh://hostname/path/to/repository/project/trunk$ svn mkdir svn+ssh://hostname/path/to/repository/project/branches
$svn mkdir svn+ssh://hostname/path/to/repository/project/tags  After that, just checkout the project: $ svn checkout svn+ssh://hostname/path/to/repository/project


You can also, easily, checkout the whole repository and run mkdir command on it:

$svn checkout svn+ssh://hostname/path/to/repository$ svn mkdir project
$svn mkdir project/trunk$ svn mkdir project/branches
$svn mkdir project/tags$ svn commit


And it is ready to get work done on the trunk/ directory.

### Accessing the repository without ssh

The commands are the same, but instead of specify the svn+ssh:// protocol, just specify svn://. Also, if the port is not default, specify it in the command line, as shown in the example below (which uses the port 21 to run svnserve):

$svnadmin create <your repository path>  Once you have been set up the repository, there are several ways to make it available remotelly. Using WebDAV is the most common way, but classical SSH access looks easier and secure, but according to the svnbook, it is not useful when used for many developers. I recommend using ssh only if it is a single user. ### Using SSH method to access the repository So, to enable SSH access to the repository, call the svnserve command, as described here: $ svnserve -t -r <your repository path>


Append the -d option to make it behave like a daemon, which means that it backgrounds itself. Useful for starting it at the system boot time.

### Using svnserve without ssh

This page recommends using svnserve without ssh when there are many developers wishing to access the same repository. It is simple to set up, effective and not really unsecure (although code surfs raw through the cable, the password never goes raw, as told in the svnbook).

So, to set it up, following svnbook, put it in /etc/inetd.conf or in /etc/xinetd.d/svnserve. See this xinetd serve example:

# default: on
# Subversion server

service svn
{
socket_type     = stream
protocol        = tcp
user            = svn
wait            = no
disable         = no
server          = /usr/bin/svnserve
server_args     = -i
port            = 3690
}


You can also run it like a standalone daemon, with the -d option.

### Authentication and access control

This page of the svnbook explains very well authentication and access control. About authentication, if we use svnserve + ssh method, we need to create a Unix account on the machine, for each user that wants to access the repository. If we use svnserve without ssh, there are several ways to make authentication (LDAP and others), but simplest way is to set up the conf/users.cfg file in the repository. Access control is made in conf/authz.cfg file (those names are flexible and configured in the conf/svnserve.conf, in the repository).

The conf/svnserve.conf file is the main configuration file, which points to the others (conf/users.cfg or authz.cfg in the examples given above).

An example of the conf/svnserve.conf file is given below:

[general]

# Global access settings.
anon-access = none
auth-access = write

# Path-specific constraints
authz-db = authz.cfg

realm = My repository name


### Importing CVS modules to a SVN repository

If you used to use CVS and is migrating to subversion, you can use cvs2svn [6] program. This cvs2svn FAQ entry teaches a way of importing one module at a time, instead of convert the whole CVS repository to a SVN repository.

Basically, the process consists in copying the cvs2svn-example.option file, modify it and run with the following command:

$cvs2svn --options=<your modified option file>  If your repository already exists (which means that you don't want to create a new one), specify it in the ExistingRepositoryOutputOption() function instead of the NewRepositoryOutputOption(). (cvs2svn version 2.1.1). ## Working with branches and tags You create a branch with svn copy: $ svn copy trunk branches/version-2-0


Subversion use the same command for both branches and tags. Therefore, the difference between them is just the use you make for it. If you never do any commit in a directory created by svn copy, it is then a tag.

To merge changes from another branch, use svn merge. You will always have to checkout at least the branch you want to merge to:

$svn checkout svn+ssh://hostname/path/to/repository/project/trunk$ cd trunk
$svn merge svn+ssh://hostname/path/to/repository/project/branches/mybranch  There can be things like conflicts on files. They normally appear if different changes were made in the same file for different branches. Resolving conflicts in subversion can be frightening. This page seems to have good tips for resolving conflicts: svn merge changes your working tree. If you do not want to do that, but only want to be sure that the merge succeds without conflicts, use the --dry-run option: $ svn merge --dry-run svn+ssh://hostname/path/to/repository/project/branches/mybranch


To rollback a commit, or a list of commits, you should also use svn merge:

$svn merge -r HEAD:140 .  This command applies a revert diff at the top of your working directory, so it changes everything to make it equal to the 140th revision of your repository (I saw this here). There are other commands that may come to help when doing merges. The command svn mergeinfo show important stuff like the common ancestor for two branches and when the last merge ocurred: $ svn mergeinfo svn+ssh://hostname/path/to/repository/project/trunk

youngest common ancestor
|         last full merge
|         |        tip of branch
|         |        |         repository path

1                  276
|                  |
-----| |------------         trunk
\          /
\        /
--| |------------         branches/ufrn
|        |
73       WC


To view merge information of a branch, use the following command:

\$ svn propget -R svn:mergeinfo svn+ssh://hostname/path/to/repository/branch


## Mirroring the repository

I sometimes want to make tests on the repository but don't want to mess with the repository history. In this situation, I create a temporary and local mirror and work there.

For this, use svnsync. There is a nice and easy howto on how to use that here.

### More references

CVS to SVN crossover guide

## Troubleshooting

### Your repo location changed, and your working copy points to the old location

In this case, just use the svn switch command, with the --relocate flag:

svn switch --relocate svn://old/svn/location svn://new/svn/location


### Cannot delete file or directory with an at sign (@) in the name

If you (deliberately or by mistake) has a file with an at sign, you will realise that you cannot delete it or even make another change using svn. This is because @ is used as a special character to separate filenames from revisions.

If you want to force it to be handled as a normal @ character, just add another @ at the end (the last one, therefore, will be handled as a special one).

svn: generic failure