DISCLAIMER: If you use svn from the command line, this post is possibly irrelevant for you.
Possibly, you have found that post in a search engine, because you have had problems when doing refactoring in eclipse in a project checked out via svn. In that case, you may not want or need any introduction. Jump right away to the best practices. However, if not, you may want to know what this is all about. This post may seem awkward, futile or even harmful to those, who have not had similar problems as me when performing – let’s say – heavy refactoring work like moving and deleting files and folders in a checked out version of an svn repository. What kind of problems could there be, you might ask. Well, mainly problems that you cannot sync or merge your version with the repository after refactoring and your checked out version is – let’s call it – broken. What could have caused breaking your version, you might ask further. Honestly, the answer is: I don’t know. Actually, svn should prevent such breaking. However, if you work with an IDE like eclipse (or derivates thereof like Flash Builder), you will need an svn plugin for eclipse. And the plugin needs an additional service provider. So, there are a quite a few of different components involved in the actual handling with the svn server that could produce errors like not updating the svn meta files appropriately, causing things to break.
So, how can this post be futile? It is futile, if you do not have any problems like those mentioned above. If you do not work in an IDE with svn but on the command line, chances are that everything works out like a charm when doing refactoring work. Maybe you even perform changes directly with commands like ‘svn move’ or ‘svn delete’. Good! Fine! I don’t. I want everything nice and integrated into my IDE. So, how can this post be harmful? Well, if you follow my best practices, you will have A LOT of different version numbers in your repository. This is not exactly harmful, as each of the checked in versions should be completely functional and working. They may, however, semantically not be actually different versions regarding their functionality. Therefore, one could regard this as bad svn style. But I don’t care. It works. It is correct.
- Always commit all changes of your (working) project before you move or delete anything.
- Do NEVER delete folders with files or folders in it. svn stores information about modified and deleted files in a (hidden) .svn folder inside each folder. If you delete files in a folder AND the folder itself, chances are that some part of the svn toolchain does not update the .svn folder in the parent directory appropriately and there is no chance of letting svn know about the deleted files inside the deleted folder. The approach that works best for me is to delete files and folders recursively starting from the submost files and folders in the file tree. Delete files in the submost folder! Commit! Update (yes)! Delete folder! Commit! Update (yes)! As i said, proceed recursively through all folders.
- Do never delete two folders at once! To be more precise, if you delete all files in a source folder respectively in a package (a folder in the source folder always IS a package) in eclipse and the subfolder is empty, eclipse tends to group these empty folders visually into one package. For instance, if you have the folder structure ‘de.johannesluderschmidt.gestures.swipe’ in which the package/folder ‘gestures’ only contains the folder/package ‘swipe’ and no other folders or files, eclipse will show only one folder/package ‘gestures.swipe’ instead of a tree structure if ‘swipe’ is also an empty folder. Therefore, if you want to delete those two folders, the only thing eclipse offers you to do is to delete both folders AT ONCE by right clicking and choosing ‘Delete’. As to point 2, deleting nested files/folders is NOT A GOOD IDEA with svn. Proceed according to 2. If this is not possible in eclipse, go to your Finder, Explorer, command line or whatnot and delete the folders according to 2 manually in the file system.
- Be aware that if you choose ‘Rename’ in the context menu of a class, there will be no simple renaming in svn. For svn, the class file you renamed will be marked as deleted and a new class file will be created with the modified contents of the old class. Therefore, stick to 1. before renaming classes.
If you somehow break the synchronization between your project and the repository, back up your copy, delete your copy (NOT the backup) afterwards, check out the repository again and join the checked out and the backed up version manually. Hence, always be sure to check in code changes before deleting or moving ANYTHING according to point 1. Otherwise, you will have living hell.
If you have additional thoughts or best practices, please be so kind to post them in the comments. I struggled so many times with svn and eclipse in the last years that I am sure not to be the only one. So please share your knowledge!
Oh, and if anyone wants to recommend using Git (or Mercurial or whatnot) instead of svn: Yes, sure, nice. Better. I know. But such a humble hint will not help anyone that has to use svn at work.