Sync task will delete files of different case on case-insensitive platforms


(andrew.oberstar) #1

The Sync task is composed of two parts, the copy of all files in the source into a destination directory and the deletion of any files that were not encountered in the source from the destination. The determination of whether a file from the destination was encountered in the source (and thus should not be deleted) is with a case-sensitive ‘String.equals(String)’ compare of the relative file paths. On Windows, for example, file paths are not case-sensitive. This means that if a file named ‘file.txt’ exists in source and one named ‘FILE.txt’ exists in the destination, Gradle will first copy the contents of ‘file.txt’ over ‘FILE.txt’ and then proceed to delete ‘FILE.txt’ since it doesn’t match names exactly.

This build script illustrates the problem.

def srcFile = file('src/file.txt')
def destFile = file('dest/FILE.txt')
  task prep << {
 srcFile.parentFile.mkdirs()
 srcFile.createNewFile()
 destFile.parentFile.mkdirs()
 destFile.createNewFile()
 assert srcFile.exists(), 'Could not create srcFile'
 assert destFile.exists(), 'Could not create destFile'
 }
  task sync(type: Sync, dependsOn: prep) {
 from 'src'
 into 'dest'
 doLast {
  assert destFile.exists(), 'Dest file was deleted.'
 }
}

Sync task misbehaving on case-insensitive file systems