public static File revert(File current, File original) throws IOException { // do nothing if current and original path is exactly the same if (current.equals(original)) { return original; } // reverse move if (current.exists() && !original.exists()) { return moveRename(current, original); } BasicFileAttributes currentAttr = Files.readAttributes(current.toPath(), BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS); BasicFileAttributes originalAttr = Files.readAttributes(original.toPath(), BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS); // reverse symlink if (currentAttr.isSymbolicLink() && !originalAttr.isSymbolicLink()) { trash(current); return original; } // reverse keeplink if (!currentAttr.isSymbolicLink() && originalAttr.isSymbolicLink()) { trash(original); return moveRename(current, original); } // reverse copy / hardlink if (currentAttr.isRegularFile() && originalAttr.isRegularFile()) { trash(current); return original; } // reverse folder copy if (currentAttr.isDirectory() && originalAttr.isDirectory()) { trash(original); return moveRename(current, original); } throw new IllegalStateException(String.format("Cannot revert file: %s => %s", current, original)); }