Getting Started With Subversion
Tuesday, July 8, 2008 | Posted in ToolsIf a good chair is A Developer's Second Most Important Asset, then revision control is probably next on the list. A good version control system enables collaboration and centralizes backups, but it's also a safety net. Any change can be undone and any file restored. Refactor, delete unused code, try out new ideas - the way it was (when it worked) is only a click away. Lowering the cost of change is a good thing.
I'm going to walk through the Subversion configuration I'm using for my repository. We'll install the application, create a repository, and add user accounts. As an added bonus, we'll configure the repository layout from the command line to veryify that everything's working correctly. For those of you familiar with CVS, there are a few key differences to be aware of:
- Repository setup isn't quite as automatic as it is in CVS. You'll need to create directories for the trunk, branches, and tags.
- You can move files within the repository without losing their revision history.
- Subversion uses repository-wide revision numbers - it's like automatically tagging every commit.
Step 1: Install Subversion.
If you're running Debian or Ubuntu, you can install Subversion using apt. Otherwise, check the subversion binary packages page for installation instructions for your distribution. We'll also need to create an account to run the svnserve daemon and a base directory to hold our repositories. You can put them anywhere you like, but for the purposes of this example I'm going to use /var/svnroot.
sudo apt-get install subversion sudo groupadd svn sudo adduser -s /bin/false -g svn svn sudo mkdir /var/svnroot sudo chown -R svn:svn /var/svnroot
Now you're ready to start the server. See the svnserve man page for details. Pay special attention to the -r option. This tells svnserve where to look for subversion repositories. It doesn't actually create a repository - we'll handle that in the next step.
sudo -u svn svnserve -d -r /var/svnroot/
Don't forget to open a hole in your firewall. The svnserve daemon uses TCP port 3690 by default, but you can specify a different value using --listen-port=port. If everything's configured correctly, you should be able to connect via telnet.
etch:~ crh$ telnet localhost 3690 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. ( success ( 1 2 ( ANONYMOUS ) ( edit-pipeline svndiff1 absent-entries ) ) )
Feel free to use this startup script as a base:
#!/bin/sh case "$1" in start) echo "Starting svnserve..." sudo -u svn svnserve -d --listen-host=svn.inscrutabledesign.com -r /var/svnroot/ ;; stop) echo "Stopping svnserve..." killall svnserve ;; *) echo "Usage: $0 [start|stop]" ;; esac
Step 2: Create a repository.
Now that svnserve is up and running, it's time to create a repository. There are two key points to remember. First, the repositories must be under the root set (with the -r option) when svnserve was started. Second, they should be owned by the same user the daemon is running as.
sudo svnadmin create /var/svnroot/examples sudo chown -R svn:svn /var/svnroot/examples
Your repository, /var/svnroot/examples, should look like this:
-rw-r--r-- 1 svn svn 229 Jul 8 22:31 README.txt drwxr-xr-x 2 svn svn 4096 Jul 8 22:31 conf drwxr-xr-x 2 svn svn 4096 Jul 8 22:31 dav drwxr-sr-x 5 svn svn 4096 Jul 8 22:31 db -r--r--r-- 1 svn svn 2 Jul 8 22:31 format drwxr-xr-x 2 svn svn 4096 Jul 8 22:31 hooks drwxr-xr-x 2 svn svn 4096 Jul 8 22:31 locks
Let's take a look at the conf directory:
-rw-r--r-- 1 svn svn 684 Jul 8 22:31 authz -rw-r--r-- 1 svn svn 309 Jul 8 22:31 passwd -rw-r--r-- 1 svn svn 1457 Jul 8 22:31 svnserve.conf
Access control options are defined in svnserve.conf. There are two different user types, ananymous and authenticated, and their permissions can be configured using the anon-access and auth-access options. Each user type can be set to "read", "write", or "none". If you'd like to deny access to anonymous users, just set "anon-access" to "none". To configure user accounts, you'll also need to uncomment the "password-db" option. Your configuration file should look similar to this:
### This file controls the configuration of the svnserve daemon, if you ### use it to allow access to this repository. (If you only allow ### access through http: and/or file: URLs, then this file is ### irrelevant.) ### Visit http://subversion.tigris.org/ for more information. [general] ### These options control access to the repository for unauthenticated ### and authenticated users. Valid values are "write", "read", ### and "none". The sample settings below are the defaults. anon-access = read auth-access = write ### The password-db option controls the location of the password ### database file. Unless you specify a path starting with a /, ### the file's location is relative to the conf directory. ### Uncomment the line below to use the default password file. password-db = passwd ### The authz-db option controls the location of the authorization ### rules for path-based access control. Unless you specify a path ### starting with a /, the file's location is relative to the conf ### directory. If you don't specify an authz-db, no path-based access ### control is done. ### Uncomment the line below to use the default authorization file. # authz-db = authz ### This option specifies the authentication realm of the repository. ### If two repositories have the same authentication realm, they should ### have the same password database, and vice versa. The default realm ### is repository's uuid. # realm = My First Repository
Once "password-db" is uncommented, creating user accounts is as simple as adding a username and password to the passwd file. If you want a little more control over what users can access, check out the authz file. You'll need to uncomment the "authz-db" line in svnserve.conf to use it. Those passwords are stored in plain text - it would probably be wise to ensure that the whole repository structure is only readable by svn user.
sudo chmod -R 700 /var/svnroot
Step 3: Create directories for the trunk, branches, and tags.
Collabnet has an excellent article on Subversion repository layout. Take a quick read through that before continuing. Once you've decided on a layout:
# Check out your repository. cd /tmp svn co svn://localhost/examples cd examples # Create a directory structure using svn. svn mkdir trunk svn mkdir trunk/example_module_1 svn mkdir trunk/example_module_2 svn mkdir branches svn mkdir tags # A layout like this is also an option. #svn mkdir example_module_1 #svn mkdir example_module_1/trunk #svn mkdir example_module_1/branches #svn mkdir example_module_1/tags #svn mkdir example_module_2 #svn mkdir example_module_2/trunk #svn mkdir example_module_2/branches #svn mkdir example_module_2/tags # Then commit your changes with a comment. You should be prompted # for a username and password if they're required for write access. svn ci -m "Created base directories."
Once your directory structure is in place you can check out the latest version of your code using:
svn co http://myserver.com/examples/trunk
That's it, you're up and running with a basic repository! There are a lot of different options available - check out the Subversion book for all the details.