Refactoring to interfaces: if only Subversion could understand

There is a refactoring I do in Eclipse sometimes that confuses Subversion:

Suppose I have a class named MessageSender.  It does not implement an interface; it just does the work itself.  Now perhaps I want a MessageSender to be an interface and have a MessageSenderImpl.  To accomplish this change, I:

  1. Rename MessageSender to MessageSenderImpl.
  2. Extract Interface on MessageSenderImpl and call it MessageSender.

At this point, I can see that Subversion is confused, because there is a little red X in the icon for MessageSender.java in the Package Explorer:

If I commit my changes now, MessageSender.java will be deleted and the build will be broken if I have any code using the new interface.

My current workaround is to:

  • Revert MessageSender.java, then
  • Replace With Previous from Local History

But this is more work than it oughter be, ain’t so?

Update 10/13/2008: Karl’s comment inspired me to post my question to the Subclipse email list, where Mark Phippard told me that an enhancement to Subclipse released in Subclipse 1.4.3 fixes this issue.  (I was using Subclipse 1.4.2).  I upgraded Subclipse to the current version (1.4.5) and now my two-step refactoring works (i.e., after step 2 the file is marked as changed rather than marked for deletion, so I don’t have to do my workaround).

Thanks, Karl and Mark!

Advertisements

, , ,

  1. #1 by Karl Fogel on October 10, 2008 - 11:39 pm

    Can you show a transcript of exactly how you did the rename and replace? Subversion should be able to handle renaming Foo to Bar, and then creating a new file named Foo, and then committing both of those changes in one commit. But, only if you do the rename in a Subversion-aware way…

    By the way, I may not see the response here (there seems to be no email-followup-on-new-comments option), but you could post to users{_AT_}subversion.tigris.org.

    (I think git may have heuristics that allow it to detect such refactorings automatically in most cases, but that’s just secondhand — I haven’t used git to do that myself.)

    -Karl

  2. #2 by danielmeyer on October 13, 2008 - 8:34 am

    Karl,
    I don’t know if it was clear that I’m using Eclipse, with Subclipse – I updated the post to say so, in case it makes a difference.

    Here’s what I did (all in Eclipse):
    1. Created new Java project
    2. Created new empty class named Foo
    3. Team -> Share project, committed project to Subversion.
    4. F2 (rename Foo.java to FooImpl.java)
    5. Shift+Alt+T, E (Extract Interface from FooImpl.java to Foo.java)
    At this point, Foo.java’s icon shows red X, signifying that it will be deleted when I commit the project to Subversion.

    I reverted twice to get back to what I initially committed, and ran an alternate step 4′:
    4′. Shift+Alt+T, N (Rename Foo class to FooImpl)
    5. Shift+Alt+T, E (Extract Interface from FooImpl.java to Foo.java)
    But again Foo.java’s icon shows the red X.

  3. #3 by danielmeyer on October 13, 2008 - 9:15 am

    As far as subscribing to comments, I don’t think there’s an email option, but you could subscribe to the RSS comment feed for this post… Comments RSS

    -Daniel-

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s