Recovering a broken Subversion working copy

There are times when a Subversion working copy can mess up. This is usually due to human error, for example due to permissions problems or moving files or folders incorrectly

These can usually be easily recoverable, although at times it can seem there’s no solution. Here are a few examples and their solutions.

Incorrectly deleting files/folders without using svn rm

This will usually result in subversion complaining when you attempt to commit. The symptom of this is the svn status giving something like:

!       path/to/missing/file

To fix this, simply issue the svn rm command for the file, and Subversion will fix and mark it as deleted.

Incorrectly moving files/folders without using svn mv

Sometimes someone may forget to run the subversion move command, and move files/folders manually. If you attempt to add a file after this, you will lose the history of the file. If you attempt with a folder, it will give an error:

svn: warning: 'path/to/moved/folder' is already under version control

The symptom of this is an svn status of:

?       path/to/moved/folder
!       path/to/old/folder

The best solution for this is to simply move it back and run the svn mv command instead.

Adding a folder with permission problems

Sometimes either the group or permissions of a folder will be incorrect. If you add the folder, it will usually issue an error like:

svn: Can't create directory 'new/folder/.svn': Permission denied

Whats worse is that the working copy now registers the folder in a half-added state. The parent folder metadata says the folder is added, but the child folder is missing its .svn metadata. The symptom of this is an svn status of:

~       new/folder

The solution is to first fix the permissions of the folder, then move the folder to a temporary location, and revert the add:

# first fix the permissions
# ...
mv new/folder new/folder2
svn revert new/folder
mv new/folder2 new/folder
svn add new/folder

An .svn metadata transplant

There are sometimes some cases that can’t be explained. The best solution I’ve found for this is to do a .svn folder lobotomy and restore with fresh .svn folders. To do this:

# backup your project in case you run into trouble
cp -Rp /path/to/project /temporary/location
# strip out the old .svn folders
find /path/to/project -name .svn -print0 | xargs -0 rm -rf
# check out a clean copy
svn co http://repo/location /temporary/location2
# move the .svn folders from the clean copy into the correct relative
# place in the <strong>broken</strong> copy
cd /temporary/location2
find . -name .svn -print0 | xargs -0 -I {} mv '{}' '/path/to/project/{}'
# remove the clean copy
rm -rf /temporary/location2