Incremental build does not work when all input files are removed

I have one project where I wondered that sometimes issuing ./gradlew build resulted in a strange test error: One test did result in an ClassNotFoundError. But… The test class did not exist. Only ./gradlew clean build solved the issue.

When thinking about it during the weekend, I had an idea. I was switching between two branches. The first branch does not contain any tests for a subproject. The second contains both a new class and a test class for this new class.

When switching from the second branch to the first, the incremental build fails. This is due to the fact that Gradle does think a compile task is up-to-date when there are no source files at all (all source files are removed due to the branch switching).

When switching from the second branch to the first, the main sources are re-compiled, resulting in the new class to disappear, but the test sources are not re-compiled, resulting in the test for the new class still being in the test classes dir. Therefore the test task does execute the test class, which results in a runtime exception.

I tried to create an integration test for this:

I am not sure, if this is a fundamental bug in the up-to-date mechanism, interestingly, running ./gradlew build --rerun-tasks does not fix this.

I am willing to try to create a fix and pull request, but would need some pointers where to trace the source of this bug.

This is a known bug GRADLE-2579.