Manipulating Subversion Repositories

Following up from the previous article about Subversion basics, let's look at some more complicated things you might want to do with your repository and your files: reverting to an earlier revision, splitting a repository and branching a repository.

Using a Previous Version of a File

Subversion allows a variety of complicated things to be done with your repository. Learn how to revert to an earlier revision, and split and branch a repository.

Say you've made some changes to a file, but have decided they're no good after all and want to go back to an earlier version. In the easy case, when you've scheduled a change but not yet committed it, svn revert filename will restore the version from the most recent commit.

If you want to reverse already committed changes, you can go back further in the history, to an earlier previous version of a particular file. To find the version you want, you'll need to look at the repository history. The command svn log will show you the basic log entries for the directory you're in, or use svn log filename to see the history for just a particular file. To include a list of files changed in each revision in the output, use the -v (verbose) switch.

To get information about the contents of a file, use svn cat or svn diff. svn diff file.txt will show you the differences between your working copy and the most recent copy in the repository. Other alternatives are:

svn diff -r 123 file.txt Compare your working copy with revision 123
svn diff -r 120:123 file.txt Compare revision 120 with revision 123
svn diff -c 123 file.txt Compare revision 123 with the previous revision (in this case 122)

Use svn cat -r 123 file.txt to show the full contents of revision 123 of file.txt.

Once you've found the revision you want, run

svn update --revision 123 filename
with the appropriate revision number to update to that revision. You can also specify PREV to go back one revision number, or give a date (format 2009-02-17), time (format 15:45, current day assumed), or both, to get the version from that point.

BE WARNED: doing this loses any changes you've made to your working version. If there may be changes you need, copy the file elsewhere first.

If you now re-edit filename and try to commit it, you'll get an "Out of date" error message, and when you run svn --update to resolve this, the file will be marked C. This indicates a conflict. Before you commit, you'll need to edit the file in question to resolve the conflict (or to ensure that it's clean), then run

svn resolved filename

Dividing Repositories

There may come a time when you decide your single repository would be better off as two repositories. Maybe you want to divide out the config files from the code or your text notes from your code. Before you start, make sure all working changes are committed (or you'll lose them when tidying up afterwards).

To get a list of the directories in the repository and decide what to move, type:

svn list file:///path/to/repository
Then use
svnadmin dump /path/to/repos > repos.dump
to get a dump of the repository (This may take a little while if you have a large repository). Next, create the directory for your new repository:
svnadmin create /path/to/newrepos

The tool svndumpfilter allows you to choose a particular directory or directories. The command you want is:

cat repos.dump | svndumpfilter include testdir | svnadmin load newrepos
This pipes the old repository through svndumpfilter, tells the filter to include only the testdir directory, and then loads it into the new repository. (You can specify multiple directories if required.)

Alt text
Some of the output from the import

All that's left to do after this is to tidy up: delete the dumpfile, delete the migrated directory from the old repository with svn delete .; svn commit (from that directory), and check a working copy back out from the new repository. And you're done!

Note: unfortunately there's no way in Subversion of removing a directory from the database altogether; if you want to do that you'll have to use svndumpfilter exclude to create a new repository without the unwanted directory.

Branching Repositories

The canonical situation where you'd want to branch is when you want to create a dev branch of a project, so that the main fork can be the stable code. (Or vice versa.) To create a new branch, you must make a copy of the main project:

svn copy /path/to/repos/proj/trunk /path/to/repos/proj/branch
Now check out that new directory to start working on the branch.

In due course, you'll probably want to merge the changes back into the main tree (e.g. to create your next stable release). This is going to be a little more complicated because chances are, you've made a few changes to the stable branch as well, and it may not be possible to automatically merge them all.

To merge changes from the trunk back to your branch, use

svn merge /path/to/repos/proj/trunk
Check for conflicts with svn status and resolve them if necessary, and run a build and any appropriate tests to check for other conflicts, then commit the changes as usual.

To merge your branch back into the trunk, first check out a clean copy of the trunk. Then run:

svn merge --reintegrate /path/to/repos/proj/branch
Again, check for conflicts and problems, then commit the changes and you're done! Now, create a new branch, and get going on your next stages of development!

There are of course many more things you can do with your repository – for example, merging two repositories. Subversion is intended to be easy to use, so most things you might want to do are possible.

This article was originally published on Apr 2, 2009
Page 1 of 1

Thanks for your registration, follow us on our social networks to keep up-to-date