Files under version control get deleted by "Clean"

Issue #351 open
created an issue

When I clean an Eclipse project which contains generated files that are under version control, the files will be in the state "Delete" afterwards. I guess this happens:

  • Eclipse sends the "clean" signal to all plugins
  • The code generator plugins delete the files -> MercurialEclipse marks the file for deletion
  • The code generator creates the file again -> MercurialEclipse doesn't add the file again

Can you please fix this? We lose a lot of time every day due to this bug: Commits often contain lots of files and the accidentally deleted files get lost in the huge list. After the commit, the files have to reverted or re-added. Sometimes, the problem leaks to other developers since they update and their tests suddenly start to fail.

PS: Migrated issue 52565 from javaforge (

Comments (21)

  1. digulla reporter

    Assuming the files are "derived files" as far as Eclipse is concerned it should be easy to change but I'm not sure it is a good idea to check in derived files and it would prevent people from ever being able to remove derived files. Probably will need to be an option in preferences. [johnpeb]

    You're right, the code generator marks them as derived.

    Maybe a first step would be to abort a commit when a deleted file still exists (i.e. when "hg" says "delete the file" but it still exists on the file system).

    Currently, mercurialeclipse silently deletes such files even when they were changed -> data loss.

    A similar work around seems to exist in the EGit plug-in. Maybe you can copy the code?

  2. John Peberdy

    The issue is not that the file is getting deleted - it will be deleted whether MercurialEclipse does anything or not in a clean. You want the file not to be recorded as being deleted by Mercurial (Mercurial calls this status "removed").

    It turns out the intent of the code originally was to not record removal for derived files but a bug prevented the rule from applying in a specific case. Tested by committing an .class file in a java project.

  3. digulla reporter

    Is this fix included in com.vectrace.MercurialEclipse_2.0.1.201209031302.jar?

    If it is, then the fix doesn't work. I still see "remove --debug --force" for derived files when I clean the project.

    If not, could you please built another snapshot so I can give the fix a try?

  4. John Peberdy

    It should be in that version. Can you paste the full runcommand line from the console - is it a file or directory that gets removed? In the Navigator View, right click on the resource and select properties.. is the 'derived' flag set?

    If no, - is the derived flag set for any of the parents of the directory? - is the derived flag set for all of the children of the directory?

  5. digulla reporter

    It only happens for files. All the files have the `derived` flag set.

    The flag isn't set for the folders that I checked. I checked folders which only contain derived files and mixed folders.

  6. John Peberdy

    Whats important is the path passed to the remove command. Use the console view to check this.

    With the current code it will invoke the remove command unless that folder is marked as derived. If clean is deleting a folder I think it should be a derived folder.

  7. digulla reporter

    I don't see how this helps but here is the full command with all sensitive information removed:

    remove --debug --force /h/x/workspace/project/a/b/src/main/java/c/

  8. digulla reporter

    Looking at your fix again, it can't solve my issue. I'm talking about *files* and the plugin should already ignore derived files (

    As the comment says, just returning false will still delete the file but it will go via tree.standardDeleteFile() which doesn't help at all.

    The correct fix is to hook into the API which is called when files are created and "hg add" the file again when it's current state is "deleted".

  9. John Peberdy

    As you pointed out the issue is with a file rather than folder. That and the presence of the 'remove' command seems to imply the file might not be marked as derived at the time clean is performed (either that or isDerived(CHECK_ANCESTORS) should be used rather than just isDerived()). Are you certain this file is marked as derived in its property page? Is there a way I can reproduce the problem using publicly available code / plugin?

    The proposed solution to invoke add when files are added would change behaviour too much as many user keep scratchpads and local config around that they do not want to be versioned.

  10. digulla reporter

    That's not what I suggest!!! I never talked about unversioned files!!!

    I'm talking about files which hg knows about, which were once addeed and which got deleted and then recreated.

    It's completely unrelated to derived files and folders.

    To reproduce:

    1. Create file
    2. Add file
    3. Commit
    4. Delete file
    5. Create the file again -> File stays in state "To Delete"
    6. Commit -> New file gets deleted and data loss happens

    This has nothing to do whatsoever with files that were never added, ignored files or derived files. The bug is solely that the plugin doesn't add files automatically when they are created AND they are currently in the state "to delete" (i.e files which are under version control)

  11. digulla reporter

    Another simple test case is to have two folders which contains each a file "foo" which are both under version control. Copy the file from one folder to the other and it will be deleted on the next commit.

  12. digulla reporter

    I just had an idea for a workaround:

    Before opening the commit dialog, get a list of all modified files, remove all files not in state "R" and then check for those files whether they exist in the workspace.

    If they exist, open a new dialog which asks "These files are marked for deletion but they still exist. Do you really want to delete them?"

    There should be a list where I can select files and the buttons:

    • Keep Selected
    • Keep All
    • Delete selected
    • Delete all

    After clicking one of the buttons, the normal commit dialog should show up.

  13. Log in to comment