Saturday, January 13, 2007

Subversion 1.5: Tolerate obstructions during checkout/update/switch

This is my second article about new features in Subversion's trunk, features that will be included in Subversion 1.5. My previous article discussed enhancements in Subversion's move/copy commands. This article will discuss improvements that have been made to the checkout, update and switch commands -- specifically, the ability to tolerate obstructions.

Prior to these changes, if Subversion needed to add a file or folder to your working copy as part of the checkout/update/switch commands, and a file or folder with the same name already existed, then the command would abort with an error. The message you receive will vary based on the command and the situation, but it will look something like this:
svn: Failed to add file 'foo.c': object of the same name already exists
As of Subversion 1.5, you can add the --force switch to any of these commands to override this behavior and tell Subversion to tolerate the obstruction. The output you normally see from these commands will tell you when this happens. For example, it will look something like this:
E foo.c
A bar.c
A new code of 'E' for 'E'xists has been added to inform you of this situation. What Subversion does in this situation is create the ".svn" meta data, as it normally would. The "pristine" copy of the file is stored based on the repository, as it always would be. The file itself, however, remains unchanged. If the file does not match the file in the repository, then svn status will show the file as containing local modifications. Those modifications can be viewed with svn diff, or committed with svn commit. Likewise, you can use svn revert to restore the local file to the pristine copy.

These changes help with a number of scenarios that can happen in normal development. The original use case that we wanted to solve was a developer that downloaded a tarball of some product and winds up making some fixes. Since they started with a tarball, they do not have a Subversion working copy on their disk. If they want to commit their fixes, or even submit them as a patch, then they need to have a working copy. With this change, they could use the svn checkout command, and the --force switch, to checkout the code from the repository on top of their local copy. When the command completes, they will have a valid working copy. They can now create a patch with their changes, or commit them if they have access.

With the code that is currently in trunk, in this scenario, the svn checkout command will still need to pull down the same number of bytes from the server as a "normal" checkout. It is possible that it could be enhanced in the future to more selectively pull down just the differences, something like an rsync. A change of that nature has been deferred for some future release or whenever someone comes along with enough motivation to tackle it.

Here is another scenario where this change solves a problem. Suppose a developer has a project checked out. They create a patch to implement some feature or fix and that patch includes some new files. They submit the patch to the community and a developer reviews and commits it. When the original developer runs the update command, the command will fail unless they remembered to remove the new files they had submitted in their patch. Now, they can just use the --force option with the svn update command, and it will complete normally and just reconcile any issues. If the patch was committed exactly as it was submitted, the developers working copy should not show any modifications after the command completes. If the patch was tweaked, then a diff of the working copy would show whatever tweaks were made, and the svn revert command could be run to get the working copy back to a pristine state, ready for the next patch to be worked on.

We will be making use of this new feature in several places in Subclipse, including several where we have had to code our own workarounds to get around this problem. There are also a couple of new checkout and project share scenarios where we should be able to utilize this new option to implement features that our users have asked for.

No comments: