Renaming files is still a pain in Subversion.

 
event

For some of my Open source projects I use Subversion. And I still kind of like it. I can use some other Source Control Managers (SCMs from now on), but when it comes to centralized SCMs my default choice is still Subversion (SVN from now on).

Do not get me wrong, I am not rambling over SVN, but it seems pretty unbelievable that such a mature and widely used has those rough edges. And they are sharp and hard to avoid.
Nothing would please me that a kind soul that reads the blog yells: “you are doing all wrong dork! Let me show you…” and continue being happy about SVN.

The Baseline

A beautiful console application of such importance that it needs a high-end, low-cost but full-blown SCM.

I created a brand new subversion repository using my favorite server install for Windows: VisualSVN and I did not bother to create the default folder structure (trunk, branches and tags) because I do not have to for this echo app.

svn001_repository

Next thing I did was to checkout my newly created repository into my working folder using my favorite client for Windows, the pretty awesome TortoiseSVN.

Then I, incrementally, build my application in my working folder and committed the changes to the repository. To do so, I used my favorite free SVN plugin for Visual Studio: AnkhSVN, and that is the reason the Solution Explorer looks like it does, with those green ticks that tell that all files are checked-in.

svn002_code

Renaming a file

Jolly as I was, I found out that MyClass does not tell what the class does, just that is mine. Let’s rename it. And then the trouble begins:

  • How many ways do I have to rename a file that has been committed to SVN with the scenario I have just described? Counting is tricky enough. Let’s enumerate them one by one
  • How do I know whether it worked? The old file is neither in the working copy or the latest version of the repository but the new file can be located in both places. And more importantly, getting the history of the new file and we should be able to see the changes for the “previous” file (or checking whether we can diff the current file with a previous version of the old file).

Outside Visual Studio. Command prompt

Nothing beats the usability of a DOS CMD prompt.

ren MyClass.cs EchoGenerator.cs

Wicked! With that line I renamed the file and broke two things in one shot: Visual Studio cannot find the old file (quite expected) and Subversion needs the new file to be added prior to commit to notice it (expected but kind of sad). I dutifully added the new file to the solution and to SVN and then I checked everything in.

Did it work? No, it did not. We are not able to track back the changes done to MyClass.cs from EchoGenerator.cs.

Outside Visual Studio. File Explorer as if it was Windows 3.1

For those who think that CMD is a misspelled synth-pop group, you can also go to the working folder and rename the file Program.cs to MyProgram.cs, fix Visual Studio solution and hope for the best…

…but the best won’t come. We have the same problem as before, the new file and the old file have no relationship for SVN.

Outside Visual Studio. Inconsolable forever

I heard the hipsters use the console a lot. I am a hipster wanna-be. Ergo I will be using SVN’s Command Line Interface (CLI for three-letter acronym lovers) and despise those who don’t to later forgive them because they “do not know any better”.
Oh, and on top of being hip I want to do the right thing, for a change.

Use the move (or mv, or rename or ren) command to rename a file:

svn mv EchoGenerator.cs Echo_Generator.cs

It still “breaks” Visual Studio as it abhors renaming files from outside. After adding the new file to the solution and committing we will be able to enjoy SVN linking the new file with the old file so that we can diff and track changes regardless of the name of the file. Yay!

Inside Visual Studio. Visual Interdev style

Go to the Solution Explorer, right click the MyProgram.cs file and select Rename and type the new name (My_Program.cs for lack of a better name). As we are in the happy nineties (I deeply pity you if you are still using InterDev) one has to go to the file, rename the class and rename all instances of the class.

Were we successful in renaming? We were indeed. With the help of of AnkhSVN we could catch the renaming file event and tell SVN to issue a move command so that we can diff the file with it renamed ancestor at will.

Inside Visual Studio. New Millennium

If we move our hands away from the keyboard to grab the mouse to renamed stuff we are doing it wrong. We can use one of the multiple refactoring tools available (ReSharper is the one for me) to rename the class and the file in one go. In our sample we will go from the obviously wrong ruby-ish name Echo_Generator to the more suitable StringMultiplicator.

But being sleek and wrong (as in not preserving the history of the file) is no fun. Not in our case, as the rename succeeded in preserving the history of the item.

What have we learnt?

Renaming files can be confusing and one can very easily remove the history connection between a newly renamed file and its ancestors.

Since we like to keep history alive we better stay inside Visual Studio and use some sort of refactoring tool (with the added bonus that we are maintaining the convention of file-per-type) alongside a SVN plugin inside Visual Studio to perform our file renames. Otherwise use SVN’s move command and fix stuff later in Visual Studio.

You’ve been warned. Freedom of choice is hurtful… in this case.

share class ,