Sunday, December 31, 2006

Installing Subclipse on Vista

Matt Woodward posted about his problems installing Subclipse on Vista. His post includes the resolution to the problem, so check it out. By the way, this is a problem with Eclipse that would effect installing any plug-in that properly declares its size in its feature.xml.

This problem has come up before on other versions of Eclipse. Apparently Eclipse includes some native code to determine the amount of free disk space. When the native code does not work right, or is not implemented, then the Update Manager thinks there is not enough free space to install the plug-ins and does not enable the Finish button on the wizard. I remember this problem happening on OS X with Eclipse 3.1. I thought they (Eclipse developers) were going to make the Java side of the code handle this better, I guess they did not.

Anyway, I am sure a lot of Subclipse users will be moving to Vista pretty soon, so hopefully Matt's post will help them get past this problem. It also looks like if I change the stated size of Subclipse to zero bytes for the next release, that will also avoid the problem. I have added issue 594 to the Subclipse issue tracker so that I do not forget to do this for the next release.

Thanks for posting Matt!

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.

Wednesday, December 20, 2006

Assigning Keys to Commands in Subclipse

The Subclipse 1.1.x releases have a new feature that allows you to assign keyboard combinations to various Subclipse commands, such as commit and update. This is an often requested feature by keyboard aficionados. The feature is built on top of the standard mechanism provided in Eclipse for assigning key combinations to commands, so if you are familiar with how that is implemented, that is probably all you need to know to get started. For the rest of us, here is how you assign a key combination to a command.

First, open the Eclipse Preferences using Windows -> Preferences. Then expand the General section of the preferences and click on the Keys preference item. You could also just type Keys in the preference filter on the top of the dialog. You should see a dialog something like this, although in this case the data has already been filled in:



In the category drop-down, you will want to select "SVN". In the Name drop-down, you can then select the SVN command you want to assign a keyboard combination to. You then tab down to the Key Sequence name field. This is where you are going to assign the keyboard combination. To do so, just type the combination you want to use. For example, in the screen shot, I have used Ctrl-Shift-C. The assignments list will show you any existing commands that have been assigned to that combination, as well as the context in which they apply. The final step is to select the context in which you want this combination to be active. The most likely candidate is "In Windows". Once you are done click the Add button and you are done. You can assign more combinations if you want, when you are done just click the OK button to close the preference dialog.

Once the combination has been assigned, you should now see that combination in the Eclipse team menu, or any other place the command you selected appears.



There have been several links to the Eclipse documentation placed within this post. I'd encourage you to read the Eclipse documentation for more information on using this feature.

Tuesday, December 19, 2006

Subclipse Synchronize Feature: Show Out of Date Folders

Recent versions of Subclipse have added a feature to the Synchronize view called "Show Out of Date Folders". This can be toggled on/off via an option on the view menu and also in the SVN Preferences. It is on by default, and I'd recommend you leave it on. The feature is a response to problems that are created for the user by Subversion's mixed revision working copies feature. See my previous post on that topic for more details and some of the issues you encounter when working with mixed revision working copies.

Historically, the Synchronize view has shown similar output to what one would get if they ran the svn status -u command. With the exception of folder adds and deletes, the svn status command will only include a folder in the list of incoming changes if the properties on the folder have been changed in the repository. However, as my previous post on mixed revision working copies articulates, if any file anywhere beneath the folder, or its children, has been modified, then the folder's revision will also have been incremented within the repository. Consequently, that means that your local copy of the folder is out of date as far as Subversion is concerned. Generally this is not a problem as most day to day activities do not require your folders to be up to date. However, there are several types of changes that you cannot commit unless the folder is fully up to date. Examples of these are if you perform an operation such as setting properties on the folder or if you want to delete or rename/refactor the folder. If you perform one of these operations, then when you try to commit the change, the commit would fail because the folder is out of date.

Just to reiterate this again, every time you commit a change to the repository, all parent folders (all the way back to the repository root) of the items you commit have their revision bumped in the repository. However, the revision of these folders in your local working copy is not bumped by a commit. The folder has to be updated with svn update in order for this to happen. This has caused a lot of confusion with users, especially since the Synchronize view should theoretically show them this.

Well, with the addition of this feature, it now does.

There was a second reason the feature was added, and that was to make update work better -- to allow the Synchronize view to help the user correctly update the folder revisions in their working copy. The Synchronize view is kind of a strange animal, although I cannot think of a better way it could work. When Subclipse populates the view, we are giving it the list of resources that are incoming or outgoing, based on the output we get from running the Subversion status API. The view then uses that list to construct the UI. If you are familiar with the view, you know that it is a tree-like view that shows the folder structure.



Since Eclipse adds the tree structure to make the UI look right, many of those tree nodes are not really there. What I mean by this is that when you select something like the tree root and choose the update option, the Subclipse code that is fired then has to ask Eclipse what you selected so that it can process the option. Eclipse gives back only the resources Subclipse gave it when the view was created, based of course on what you have selected. Subclipse does not receive back the tree nodes that Eclipse created for the UI.

We tried several techniques where we would figure out the UI element you selected and then try to do the right thing, but nothing ever worked perfectly. What worked best was to just update the resources that Eclipse told us you selected. However, this is where the update problem surfaces. Since svn status -u typically does not include folders, Subclipse typically never receives folders as items to update. Consequently, when you would run update from this view, your folders would never get updated and would always be out of date. This feature fixes this problem, as folders now show up as changes and therefore are included in the selections. This has allowed Subclipse to resolve all of the issues we have fought with on getting update to work the way we want from this view.

Of course, there is something of a negative side-effect to this feature too. Namely, that most the time you do not really want to see this extra information. Also, after you commit some files, you are always going to have incoming out of date folders (because that is how Subversion works). There really isn't any way around this. The folders are out of date after a commit, so the view shows them. Now that Subclipse is giving you all the information you need, you are at least armed with the information you need to decide when you want to update those folders.

Update: I rewrote the 2nd paragraph into what is now the 2nd and 3rd paragraph in an attempt to explain this more clearly. It is definitely a hard thing to explain clearly.

Subversion Move/Rename Feature

I have read a lot of mailing list threads the last couple years where projects debate whether to move from CVS to Subversion. Usually this happens when their hosting provider adds Subversion support, as the Eclipse Foundation recently did: #131096. I see two primary features in Subversion that are mentioned when people want to switch:
  1. Support for atomic transactions.
  2. Support for tracking move/renamed files and folders.
Anyone that has ever been burned by the lack of atomic transactions in CVS knows the value of having that feature, and I'd argue the presence of that feature alone justifies the transition to Subversion. However, I'd also say that even more people mention wanting improved support for move/rename as the big reason for switching.

Here is the problem. The support for move/rename in Subversion is often not what user's expect it to be.

The support for move/rename in Subversion is really about maintaining history. If I rename a file, commit it and then examine its history, I can see the history of the file all the way back to when it was created, across any move boundaries. Likewise, if I want to get a copy of what a file looked like last year, I can do so without needing to know what the file was named last year. If these are the sort of features you are after, then Subversion provides them very well.

So what are the features that Subversion does not provide? For starters, you might want to take a look at issue #898 in the Subversion issue tracker.

Subversion implements a move/rename as a copy followed by a delete. The fact that the new file is a copy is the reason you get support for the previous history. The negative side effect of this can be seen in this simple scenario:
  1. Suppose you have a versioned folder named foo with a file named bar.
  2. Users A and B checkout foo to make some changes.
  3. User A renames bar to baz and commits the change.
  4. User B makes some changes to the code in bar and attempts to commit. The commit fails because bar is out of date. So far this is all normal and expected. User B then runs svn update. What happens?
  5. svn update will add new file baz to the working copy of user B, and bar will remain in the working copy as an unversioned file (if it did not contain modifications it would have been deleted). I think that most people would expect that the local copy of bar would be renamed to baz and now contain user B's changes merged with whatever changes were in the repository as a normal update would do.
  6. User B has to recognize this is what happened and transfer the changes to baz before committing. Of course, they might also run svn add on file bar to put it back and then commit it. Perhaps because they did not really recognize or understand what happened.
This is just a trivial example that shows a potentially big problem. Imagine the above scenario played out as a large refactoring -- which is entirely possible since that was one of the motivations in moving to Subversion to begin with.

This problem also manifests in other commands like merge. Imagine you have a branch with some customizations you are working on. A refactoring happens on trunk which involves the renaming of several files and folders. You now have lost the ability to use merge to bring the changes in the branch back to trunk, or vice versa. Or, more accurately, you have lost a lot of the automation that Subversion can normally perform for you during this operation.

If you read the referenced issue from the Subversion issue tracker you will see that solving this problem is a big challenge. I would not take the lack of this feature as a reason to not use Subversion, obviously I'd recommend that you DO use Subversion. However, it is important to understand how the tool works and what it does and does not do before making the switch. My big fear would just be for a project to switch so that they could do a bunch of refactoring work and then run into this limitation in Subversion and become angry. I think the advantage Subversion gives you is that you often can do those refactorings and take advantage of the history support that Subversion provides. However, if you are going to do this, you need to use communication with the rest of the team and try to coordinate it in a way that it does not impact the entire team.

Monday, December 18, 2006

Mixed Revision Working Copies

Subversion includes a powerful and useful feature known as Mixed Revision Working Copies. However, aspects of this feature regularly cause problems and confusion to new users of Subversion and its various clients like Subclipse. Problems related to this feature come up so often on the Subclipse mailing list that we had to create an FAQ for it.

The definitive explanation of mixed revision working copies can be found in the book that is maintained by the Subversion developers. See: Mixed Revision Working Copies. I'd encourage you to read this explanation, and really the entire chapter contained on the linked page, to gain a better understanding of Subversion and how it works. The following passage summarizes the feature:
"For example, suppose you have a working copy entirely at revision 10. You edit the file foo.html and then perform an svn commit, which creates revision 15 in the repository. After the commit succeeds, many new users would expect the working copy to be entirely at revision 15, but that's not the case! Any number of changes might have happened in the repository between revisions 10 and 15. The client knows nothing of those changes in the repository, since you haven't yet run svn update, and svn commit doesn't pull down new changes."
The end result of this example is that, after the commit, the file foo.html is at revision 15, but the rest of the working copy, including the parent folder of foo.html, is still at revision 10 and will remain at revision 10 until you run svn update.

This scenario trips up inexperienced users later on when they attempt to do something like commit a property change on the parent folder of foo.html or perhaps rename the parent folder. Subversion will not allow a property change, rename or delete of a folder to be commited unless the folder is at its HEAD revision in the repository. When you attempt to commit an item in this scenario, the commit will fail with an error message like this:

Transaction is out of date
svn: Commit failed (details follow):
svn: Out of date: '/Project1/src/folder1' in transaction '1221-1'

The solution at this point is to run the svn update command so that the folder in your working copy is updated to its HEAD revision. Of course all of this is also true for files. The difference is that with files it is much easier for the user to understand when and why they get out of date as it only happens when an explicit change is made to the file or its versioned properties.

In my opinion, users that are using a graphical Subversion client, or IDE integration, are much more likely to run into this problem than someone that uses the command line. The reason is simple, command line users are likely to simply run the svn update command at the root of their project in order to save typing. This has the beneficial side effect of bringing all of the folders in the working copy up to date with the repository. Conversely, a user in a graphical client will often take operations in a context that results in actions only being performed on the specific selections. In Subclipse, as an example, many users use the Eclipse Synchronize view to see all incoming and outgoing changes. This view encourages the user to only commit and update the specific files that have been modified, making it more likely that they will run into this issue.

Subclipse Live Annotations

One of my favorite features in Subclipse is the support for Live Annotations, also called Quick Diff Annotations. This was a feature that was added in Eclipse 3.2 and is supported in the Subclipse 1.1.x versions. The feature was added to Subclipse by Brock Janiczak.

Enabling the feature is easy. When you run the Team -> Show Annotations option on a file, you are asked if you want to show the annotations using Quick Diff:


Just answer Yes, and the source in the editor will be color-coded in the quick diff area with the annotation information. Hover your mouse over one of the colored-bars and you will see the revision, author and log message for that annotation.



This is a great feature as it allows you to continue working in the editor but still have easy access to the annotation information for the file you are editing. Eclipse 3.3 adds additional controls to how the revisions are color coded. I have not tried 3.3 yet, so I do know exactly what you can do, but I will be sure to check out the feature when I do. The feature itself is an Eclipse feature so the preferences to control it would in one of the Eclipse pref panels. Subclipse does its part to enable the feature to work properly with Subversion annotation information.

Friday, December 15, 2006

Dice-K!

Earlier this week the Red Sox finalized a deal with Daisuke Matsusaka for 6 years/$52 million. When you factor in the $51 million they paid for the right to negotiate with him they paid over $100 million to get him. Like a lot of people, I am concerned that the Sox have essentially turned into the Yankees. Money appears to be no object and they just spend and spend some more and raise the ticket prices. This does change our identity quite a bit, as historically we have liked to portray the Yankees as the Evil Empire where we were the good guys. Now, I do not think there is much difference between us.

Despite these reservations, I think this was a good deal and will be a good deal. First, he seems to be worth the money and will be capable of being their ace right out of the gate. Second, this keeps him away from the Yankees. But third, and most important in this case, this is going to be a huge revenue generator for the team in the Japan market. There will be an almost unlimited number of ways for the team to pull new revenue out of Japan. When you factor that in, and deduct it from what they are paying him, it becomes a very good deal.

The Sox now have 5 good starters, 4 of whom could potentially be the ace of many staffs. They potentially will also get Jon Lester back. All the team really lacks is a closer. Unfortunately, that is a bad thing to lack. I suspect they will get to the playoffs with this team, but winning it all will be very hard if they do not develop or acquire a closer over the course of the season. I'd like to see them have Craig Hansen start the season in Pawtucket, or where ever they need to put him, so that he can develop what he needs to be the closer down the stretch. It seems like he just needs to add some polish to some of his pitches and learn more about when to use them. He has the raw materials.

Anyway, how many days until Spring Training? I can't wait.

First Post

This is the obligatory first post. What do I intend to do with this blog? Basically, I want to write about Subversion. I have not quite decided how I am going to do it, I imagine it will be a bit of trial and error. I am thinking of doing some form of schedule. Maybe one day will be a Subclipse tip or feature, one day a general Subversion tip or feature, one day post news from Subversion or Subclipse, such as a new feature in trunk. Maybe a news day where I link to some other Subversion and Subclipse information, and finally an essay day where I make a longer post about something with Subversion or Subclipse.

Of course, I also intend to post about other topics I am interested in or comment on something I read. We'll see and let this evolve over time.