It snapshots everything in order to see if the task is up to date or not. If the sources and the target haven't changed since the last time the task was run, then Gradle optimizes it by not doing anything, and the task is marked as UP-TO-DATE.
My guess is that they don't try to be smart and determine exactly which files of the target directory must be snapshotted because the copy task also accepts include
and rename
closures, and the task thus can't assume that nothing won't end up being copied to the important
folder.
In general, Gradle works better (and assumes) that every target directory can be cleaned, and that a target directory isn't shared by two separate tasks.
I've not tested this workaround, but I would try defining my own task, using Project.copy(), and specifying its inputs and outputs explicitely and precisely, in order to not lose incremental deployment.