Saturday, October 19, 2013

Reverting to a previous revision with Subversion

One of the great advantages of using a version control system to manage source code is that you never lose the history of changes to your software project.  You can always see what a file looked like at any point in the past.  Sometimes, you need to take this a step further and actually revert a file (or files) back to an earlier version.

Taking a file back in time is only rarely necessary (in my experience, anyway – I suppose it depends on how a project is managed).  As a result, it is one of those things that I always forget how to do by the next time I need to do it.  So, this is a short post discussing how to achieve this with Subversion.

First, what about the Subversion command svn revert?  To avoid any confusion:  This command simply reverts any local changes (i.e., uncommitted changes) to a working copy of one or more files.  Thus, it does not make any changes to the repository and therefore does not do what we need.

The key to reverting a file to a previous revision is the svn merge command.  The general idea is to do what is known as a "reverse merge."  In a nutshell, you tell svn merge to make your local working copy look like a previous revision, then use svn commit to send these changes to the repository.

Suppose that the latest revision of a project is 270, and we need to roll all of the files in some directory back to revision 240.  Here is the merge command to do this.

svn merge -r 270:241 https://repository.location/path/to/directory

The key is the argument "-r 270:241", where we specify the two revisions to compare.  Here, we're finding the differences between the latest revision, 270, (the "left side" of the comparison) and revision 241 (the "right side" of the comparison), and then applying the differences to the local working copy (assumed to be the local current directory in this form of the command).

If the merge is successful, then svn commit can be used to make the changes official, and you're done.

The additional argument "--dry-run" is also useful to know.  By adding this to the end of the svn merge command, you can see a summary of what changes svn merge would make without actually altering any local files.  Of course, if you do the merge and then decide you made a mistake, you can simply run svn revert to undo the changes to your working copy.

For more details, see the section "Advanced Merging" in the official SVN book, Version Control with Subversion.