General Subversion notes

This page contains my notes on Subversion, many of which are to do with what I'd consider unexpected behaviour - that which either veers from normal Linux file manipulation or defies my assumptions of what a repository should do ;-)

Subversion is very nice when it works, but there are a few things that bug me:

  • You can't easily attempt to combine normal file manipulation operations and the svn couterparts. Despite the syntactical similarity of basic operations they differ in their handling of arguments (e.g. wildcards). So if you want to use the command-line at speed you have to be really careful when switching between normal Linux file commands and Subversion's.
  • In my experience, the Berkeley DB back-end isn't too reliable and Subversion isn't very good at recovering your working (local) copy after errors (i.e. after partial commits).
  • Any repository that has the capacity to return an error saying "svn: warning: 'dir' is already under version control" one minute and then "svn: 'dir' is not a working copy directory" the next is pushing it a bit. See here for an Example of annoying subversion errors.

Saying that, it's still a hell of a lot nicer than CVS :-)


Move multiple resource with svn mv | Go to top

From ~:caboose.

The svn mv command can only move a single resource at a time. To move multiple resources, use the shell. For example, to move all .css files from v1/ to v1/css/, do the following:

   for I in v1/*.css; do svn mv $I v1/css/; done;

Checkout a particular revision | Go to top

To check out a particular revision, based on revision number or date, see this page from the Subversion book: Revisions: Numbers, Keywords, and Dates, Oh My! Chapter 3. Guided Tour.

Recursively add resources to version control | Go to top

See Adding all new files with SVN.

If you want to add a number of resources to svn, you can pipe a list of all unversioned filenames (retrieved with the aid of grep and awk) through xargs into the svn add command.

svn status | grep "^\?" | awk '{print $2}' | xargs svn add

If you want to add a number of resources to svn, you can pipe all relevant filenames (with the aid of grep) through xargs into the svn add command.

So, to recursively add every resource under the current directory (files and folders) that is not already under version control...

find ./ | grep -v svn | xargs svn add

Recursivly delete .svn directories | Go to top

To recursively delete all .svn directories:

find . -name .svn -print0 | xargs -0 rm -rf

See for source.

Revert to latest revision | Go to top

svn revert file

This command will revert the file to the most recent one in the repository, overwriting any local changes. To revert the contents of a directory either use the -R flag (recursive) or use a wildcard. i.e. Use svn revert dir -R or svn revert dir/* will.

Restore old revision | Go to top

svn update -r[revision number]

mv command oddities | Go to top

svn mv and when it changes the local filesystem

svn mv whatever wherever will move whatever to wherever but will keep the directory hierarchy of whatever until you commit. e.g. svn mv dir . creates dir (with contents) in . but also leaves empty directory structure in the original dir. It will remain there until you commit.

Don't attempt to move a versioned directory into a non-versioned one

You can not move a directory that's already under version control to one that's not. E.g. if /dir/dir2 is under version control and /dir1/dir3 is not, svn mv /dir1/dir2 /dir1/dir3 doesn't work.

cp command oddities | Go to top

Differences between Subversion cp command and the standard Linux cp command

See Subversion cp annoyance to see why the svn cp command REALLY gets on my nerves.

Subversion "soft" copying

When using the svn cp command to copy a directory, svn will do a kind of "soft" copy of the directory and it's contents. This is because subversion is only really creating a link to the copied directory - it only tracks the differences between files. Hence, when you query the status it will only list the directory as scheduled for addition to the repository and not the directory contents. The difference is indicated with a + symbol. So if you do svn copy dir1 dir2, svn will copy dir1 to dir2, but svn status will only list A + dir1.

Recover from failed commit | Go to top

If your commit fails half way through (because of network problems for example) then your working (local) copy and the repository will be out of sync.

For example, consider the following actions:

  1. You create a new directory called dir, populate it with contents and add it to subversion with svn add dir
  2. You run svn commit dir
  3. The commit hangs half way because of network problems.

Now you're in a situation where your working copy is out of sync with the repository. If you try the commit again you'll probably get an error:

svn: Working copy '/location/of/locked/directory' locked svn: run 'svn cleanup' to remove locks (type 'svn help cleanup' for details)

Unfortunately svn cleanup is not recursive (if it's meant to be recursive it doesn't work!), so run svn cleanup /location/of/locked/directory every time you receive this error message. When svn stops complaining you should be able to commit.

Relocate working copy after change in repository URL | Go to top

If the repository URL changes you can relocate the associated working copy using the following command:

svn switch --relocate http://url/of/old/resource http://url/of/new/resource

I believe this can be done for local repositories too:

svn switch --relocate file:///location/of/old/resource file:///location/of/new/resource

Here's the svn switch documentation.

svn: Working copy '/directory/under/version/control' locked | Go to top

If, when trying to commit, you get the message svn: Working copy '/directory/under/version/control' locked, it's likely that subversion has reference to /directory/under/version/control in one of it's entries files when it doesn't actually exist on the filesystem.

In my case, Subversion was complaining that /mnt/store/cal/svn/personal/steph/projects/project-one/diagrams was locked. The 'diagrams' directory did not actually exist on my filesystem but the contents of /mnt/store/cal/svn/personal/steph/projects/project-one/.svn/entries was as follows:

<?xml version="1.0" encoding="utf-8"?>

This indicates that Subversion has scheduled the 'diagrams' directory for addition. It was probably due to my adding the 'diagrams' directory to version control but then manually deleting it (using the bash rm command). I should have committed it to the repository and then deleted it using the svn rm command.

Anyway, the only way I could find to correct the problem was to manually edit the entries file and remove reference to the 'diagrams' directory.

View log for particular revision | Go to top

To view the log for revision 265:

svn log -r 265

Add/edit/remove users | Go to top

Warning: Be careful with the switches/flags because it's easy to overwrite existing configuration.

This describes the user setup for Subversion via Apache, when using mod_dav and mod_dav_svn. The access config is normally stored in files in /var/svn/conf/.

Use the htpasswd2 command to add/edit/delete users.

Add user

If you already have some users, the password file [filename] will already exist.

htpasswd2 /var/svn/conf/[filename] [username]

The -c flag will create a new file, so don't use it if you only want to add a user to an existing file otherwise you'll overwrite the entire file (hence delete all existing users).

htpasswd2 -c /var/svn/conf/[filename] [username]

Edit user

This is the same as creating a new one.

htpasswd2 /var/svn/conf/[filename] [username]

Delete user

htpasswd2 -D /var/svn/conf/[filename] [username]

Specifying password on the command line as an argument

In all examples, you can use the -b to allow you to specify the password as an argument rather than being prompted for it. e.g:

htpasswd2 -b /var/svn/conf/[filename] [username] [password]

Config file details

The path /var/svn/conf/ and [filename] are dependent on your setup. On Gentoo, look in /etc/apache2/conf/modules.d/47_mod_dav_svn.conf (or similar) for further details.

For more on the Apache authentication file, see Edit the Apache .htpasswd authentication file.

Tag or branch a release | Go to top

Tagging and branching is done with the copy command.

svn cp trunk tags/REL-0.1
svn commit -m "Tagging release 0.1."
svn cp trunk branches/RB-0.1
svn commit -m "Branching release 0.1."

Replace a file with an older revision | Go to top

Do a reverse merge. See Chapter 4. Branching and Merging from the subversion manual. For example, to replace style.css with revision 44, do the following. Note that the first location must be the repository URL, the second can be the working copy.

svn merge -rHEAD:44 file:///home/bn/repositories/website/trunk/css/style.css css/style.css

Query current revision of working copy | Go to top

Run the following command:


Read more about it on the page for svnversion in the online book.


Last modified: 01/04/2009 Tags: (none)

This website is a personal resource. Nothing here is guaranteed correct or complete, so use at your own risk and try not to delete the Internet. -Stephan

Site Info

Privacy policy

Go to top