Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-17267

Git clean or wipeout workspace follows junction on Windows slaves

    • Icon: Bug Bug
    • Resolution: Won't Fix
    • Icon: Major Major
    • core, git-plugin
    • None

      A job is configured with Git SCM, and either "clean after checkout" or "wipe out workspace before build" option is enabled.
      If the workspace contains a 'directory junction' (Windows slave) then, the "clean"/"wipeout" will follow the symlink (junction), and will delete files in the directory referenced by this symlink, and not just the symlink.
      This is a problem since other jobs are using these files...
      NOTE: it only affects Windows slaves; when a similar job is run on a Linux slave, it does not follow symlinks.

          [JENKINS-17267] Git clean or wipeout workspace follows junction on Windows slaves

          I have the exact same issue.
          The "Workspace Cleanup Plugin" works ok - not following symlinks - at version 0.16 though.

          Vincent Kessler added a comment - I have the exact same issue. The "Workspace Cleanup Plugin" works ok - not following symlinks - at version 0.16 though.

          Daniel Beck added a comment -

          Same issue occurs when using 'Wipe Out Workspace' so more of a core issue than git I think.

          Workaround is to use directory symbolic links (mklink /d) rather than junction points (mklink /j).

          Daniel Beck added a comment - Same issue occurs when using 'Wipe Out Workspace' so more of a core issue than git I think. Workaround is to use directory symbolic links ( mklink /d ) rather than junction points ( mklink /j ).

          Daniel Beck added a comment -

          It doesn't help that the Java runtime (maybe assisted by Windows) claims that junction points are a directory.

          Create a new freestyle project named JENKINS-17267, add a Windows Batch build step:

          mklink /d s c:\existingTargetFolder
          mklink /j j c:\existingTargetFolder
          md d

          Build once. Then open Script Console and run the following script:

          def s = new File(Jenkins.instance.getItemByFullName('JENKINS-17267').someWorkspace.child('s').getRemote())
          def j = new File(Jenkins.instance.getItemByFullName('JENKINS-17267').someWorkspace.child('j').getRemote())
          def d = new File(Jenkins.instance.getItemByFullName('JENKINS-17267').someWorkspace.child('d').getRemote())
          [s, j, d].each {
            println java.nio.file.Files.isDirectory(it.toPath())
            println java.nio.file.Files.isDirectory(it.toPath(), java.nio.file.LinkOption.NOFOLLOW_LINKS)
            println java.nio.file.Files.isSymbolicLink(it.toPath())
            println ""
          }
          return

          Output:

          true
          false
          true
          
          true
          true
          false
          
          true
          true
          false

          In other words, a pure Java program has no chance to distinguish between a junction and an actual folder.

          Daniel Beck added a comment - It doesn't help that the Java runtime (maybe assisted by Windows) claims that junction points are a directory. Create a new freestyle project named JENKINS-17267 , add a Windows Batch build step: mklink /d s c:\existingTargetFolder mklink /j j c:\existingTargetFolder md d Build once. Then open Script Console and run the following script: def s = new File(Jenkins.instance.getItemByFullName('JENKINS-17267').someWorkspace.child('s').getRemote()) def j = new File(Jenkins.instance.getItemByFullName('JENKINS-17267').someWorkspace.child('j').getRemote()) def d = new File(Jenkins.instance.getItemByFullName('JENKINS-17267').someWorkspace.child('d').getRemote()) [s, j, d].each { println java.nio.file.Files.isDirectory(it.toPath()) println java.nio.file.Files.isDirectory(it.toPath(), java.nio.file.LinkOption.NOFOLLOW_LINKS) println java.nio.file.Files.isSymbolicLink(it.toPath()) println "" } return Output: true false true true true false true true false In other words, a pure Java program has no chance to distinguish between a junction and an actual folder.

          Jesse Glick added a comment -

          I think there is nothing to be done beyond advising people to not use junctions.

          Jesse Glick added a comment - I think there is nothing to be done beyond advising people to not use junctions.

          pjdarton added a comment - - edited

          jglick I think that this one has been resolved by JENKINS-29956.

          FYI advising folks "to not use junctions" isn't viable - you might as well advise folks not to use Windows
          Windows has hard-coded functionality preventing most people from creating Symbolic Links (you need to be a non-admin user who's been granted the right to create symbolic links, or you need to be running "as administrator" with no protection) and so the only remaining option is to use a "directory junction" (which anyone can create).
          It's a pain in the ^%$£ but it's the only option for most users on Windows.

          pjdarton added a comment - - edited jglick I think that this one has been resolved by JENKINS-29956 . FYI advising folks "to not use junctions" isn't viable - you might as well advise folks not to use Windows Windows has hard-coded functionality preventing most people from creating Symbolic Links (you need to be a non-admin user who's been granted the right to create symbolic links, or you need to be running "as administrator" with no protection) and so the only remaining option is to use a "directory junction" (which anyone can create). It's a pain in the ^%$£ but it's the only option for most users on Windows.

          Jesse Glick added a comment -

          Avoid using junctions or symbolic links.

          Jesse Glick added a comment - Avoid using junctions or symbolic links.

            Unassigned Unassigned
            skrm Laurent ERNES
            Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: