Thursday, December 21, 2006

Subversion 1.5: Improvements to move/copy commands

This is not an announcement of Subversion 1.5, and no, I do not have any idea when it will be released.

There are a number of nice enhancements to Subversion in trunk and these should therefore all be included in the next release, which will be 1.5. One such feature that I personally asked for was improvements to the copy and move commands. If you read my recent post on the move/rename process, you might assume that these enhancements address that problem -- they do not. Resolving that issue will be a major change that will probably not come until a 2.0 release, if ever. There were some other limitations in the copy/move process, and these really effect Subclipse users. Fortunately, in this case, the limitations were just an implementation issue, there was nothing in the Subversion design that caused them.

OK, enough already, what is the new feature? Prior to these changes, Subversion did not allow an item that was copied/moved to be copied/moved again until it had been committed. If a folder was copied/moved, then its children could not be copied/moved until the folder and children are committed. This is a huge limitation for Java users, especially when they want to use the refactoring tools provided by Eclipse. Let's give an example:

Suppose you have a Java package named: org.eclipse.project.core with a class in a file named Plugin.java. Now suppose you want to refactor the package name to be org.eclipse.project.internal.core and also refactor the class and file name to ProjectPlugin.java. When you try to do this, moving the folder to the new name would work OK, but when the refactoring got around to renaming the class file, it would fail with an error like this:

svn: Cannot copy or move 'Plugin.java': it's not in the repository yet; try committing first

Subclipse performs some gymnastics to detect this situation and workaround it, but part of that workaround means not using the svn move command, which means the file history is lost.

Fortunately, with Subversion 1.5, all of these limitations are now removed. The copy/move API's can now handle all of these scenarios and do the right thing. This allows us to remove all of our workarounds from the Subclipse code and just let Subversion handle everything as it should. The refactoring experience within Eclipse should become much nicer once Subclipse is up to this version.

Addendum: Some users of various Java Subversion integrations may be aware of SVNKit, formerly known as JavaSVN. SVNKit, has contained code that could handle this situation for a long time. They called the feature SmartMove and some of the tools that are based on SVNKit use it. Subclipse uses SVNKit via an Interface where it is mimicking the capabilities of the Subversion Java API (JavaHL), including its limitations. So this note is just to explain why Subclipse does not support this feature when SVNKit is being used.

1 comment:

Daniel Rall said...

While somewhat orthogonal to Mark's post, Subversion's copy and move commands have also grown the ability to specify multiple source targets, and now have modal behavior for whether to position source targets under an existing destination directory or error out if the destination already exists.

Subversion's JavaHL bindings now expose this functionality, which will be available in the 1.5.0 release.