I think this logic is wrong.  Shouldn't it be:

  if (forceContentCheck) {
    if (fileLastModified == cacheLastModified)
      return false; // Same time, don't check content.
    else
      return !getEntryObjectId().equals(entry.getObjectId());
  } else {
    // No content check forced, assume dirty if stat differs.
    return fileLastModified != cacheLastModified;
  }

Basically, isn't the meaning of forceContentCheck that you want to "refresh the index", aka update the stat information for a path to match what is in the working directory if the file contents are the same?  Its not to fix the racily clean problem, its to fix paths where the user has touched the file but not actually made changes to its contents.

Racily clean should be handled differently, but also should force a content check.  To handle racily clean, you would check for racily clean condition side of the forceContentCheck block above before testing the file modification times, and do the content check there.

Right now your code is doing content checks on files that are unchanged, and are proven to be unchanged by stat information.  That hurts on a big repository.