Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 298441

Summary: Eclipse modifies and deletes .svn folders on projects managed with SubVersion
Product: [Eclipse Project] JDT Reporter: I.E. <inibehe>
Component: CoreAssignee: JDT-Core-Inbox <jdt-core-inbox>
Status: CLOSED INVALID QA Contact:
Severity: normal    
Priority: P3 CC: eclipse, remy.suen
Version: 3.6   
Target Milestone: ---   
Hardware: All   
OS: Mac OS X - Carbon (unsup.)   
Whiteboard:

Description I.E. CLA 2009-12-22 17:04:53 EST
Build Identifier: 20090920-1017

Summary:

Scenario: You have a project of files and folders that are under version control with SubVersion (including binary files in the bin/ folder), and the Subclipse plugin is not used. When this project is opened and auto-compiled in Eclipse Java IDE, Eclipse will modify files in /bin/.svn/*. Examples:

<Your Project>/bin/.svn/entries     <-- Eclipse modifies this file
<Your Project>/bin/.svn/prop-base/  <-- Eclipse deletes this folder
<Your Project>/bin/.svn/text-base/  <-- Eclipse deletes this folder

Normally, the folders prop-base/ and text-base/ will be deleted. The files in these folders are internal to SubVersion, and are used to track changes to files. Also the "entries" file will be modified.

The result of this is two unfavorable things:

1) You will not be able to commit changes to any files in bin/, because SubVersion will think they are no longer under version control. The SubVersion client SmartSVN will show these files as Local State = "Unversioned" and Remote State = "Unchanged". This is a very odd state to be in.

2) Because the "entries" file was modified by Eclipse, SubVersion thinks that some auto-generated source files should be in bin/ , and shows the Local State = "Missing" for these files in their original location. This is also wrong.


Root Cause:

When Eclipse builds your code, it copies the .svn sub-directory from the src directory into the output bin directory. Yup, you heard that right: Eclipse overwrites the .svn sub-directory in bin when it compiles.[1]

This is a difficult problem to spot and diagnose, and there are very few solution guides online.


Workaround (only partially working):

Eclipse -> Package Explorer -> right-click your Project -> Properties -> Java Build Path -> Source -> unfold your project/src -> Excluded -> Edit... -> Exclusion patterns -> Add -> **/.svn/* [2]

This workaround is fairly tricky and most people would spend a lot of time looking in Eclipse Preferences (perhaps in Team -> CVS) to try to fix it, but find nothing.

However, I find that this only protects /bin/.svn/
If you have your Java classes arranged in a package like "com.project", then the following svn folders will still be deleted:

/bin/com/.svn/
/bin/com/project/.svn/


Suggestion for Fix:

By default, Eclipse should not modify/overwrite or delete any .svn folders in the project. The correct behaviour seems to happen with CVS folders, but not with .svn folders. This probably should not need a preference to enable or disable.


Credit for Explanation and Workaround:

[1] http://pyre.third-bit.com/blog/archives/101.html

[2] http://pyre.third-bit.com/blog/archives/101.html ==> comment #9 by George F on August 30, 2007 and comment #4 by DaSH on December 1, 2005.

Reproducible: Always

Steps to Reproduce:
1. In Eclipse, create a Java project in a package like com.project, for example. Use "bin" as the output folder.
2. Put this project into a SubVersion repository
3. Check out this project. Ensure that you see ".svn" sub-folders in every folder.
3. Open this project in Eclipse. Ensure that auto-compile is on.
4. Notice that after compile, Eclipse has modified /bin/.svn/ . Also notice that /bin/com/.svn and and /bin/com/project/.svn are both deleted.
5. Notice that you cannot commit changes to any files in bin.
6. Try the workaround, but notice that it only protects /bin/.svn
Comment 1 Walter Harley CLA 2009-12-23 12:42:26 EST
Thanks for the considerable work you've put into tracking this down and describing it.  However, I believe this is working as designed.  

Firstly, your output folder should not be version controlled.  It's an OUTPUT folder.  If you need to have checked-in binaries, put them into a source folder, and let Eclipse copy them into the output folder.  If your checked-in binaries have to live in "bin", then make your output folder be named something different.  

You may be able to get it mostly working (see the next point below) but it is not likely to work seamlessly - Eclipse is just not very happy mixing input and output into the same folder.  And frankly, while this is just one developer's opinion, I agree with it: I think it's bad practice to combine version-controlled files with non-version controlled files in the same directory.  Makes it too easy to accidentally forget to check something in.

Secondly, if you have "special" files or folders in your source folders, that you don't want copied over to the output, you need to tell Eclipse that.  How else should it know?  Certainly Eclipse should NOT do anything special about ".svn", nor about the hundreds or thousands of other files/folders with names that mean something special to some third-party tool or other, unless it is told to.  And since any name or pattern can be special to something, it doesn't make sense to have individual options for every single possibility. 

If you were using Subclipse, a special rule for ".svn" would be added automatically, just as it is for CVS (support for which just happens to be included in the Eclipse distribution you're using).  Since you're not, you need to add it yourself, manually.

So, two recommendations for you: first, separate out your version-controlled files from your output folder; second, install Subclipse, even if you don't intend to do your version control actions within Eclipse, or at least manually add exclusions for ".svn" and any other similar names that have special meaning to Subversion.
Comment 2 I.E. CLA 2010-01-04 07:21:36 EST
Thanks for your prompt reply and suggestions. I will probably start using Subclipse.