public boolean sync() throws IOException {
    if (!preSyncCheck()) {
      return false;
    }

    if (!getAllDiffs()) {
      return false;
    }

    List<Path> sourcePaths = context.getSourcePaths();
    final Path sourceDir = sourcePaths.get(0);
    final Path targetDir = context.getTargetPath();
    final FileSystem tfs = targetDir.getFileSystem(conf);

    Path tmpDir = null;
    try {
      tmpDir = createTargetTmpDir(tfs, targetDir);
      DiffInfo[] renameAndDeleteDiffs =
          getRenameAndDeleteDiffsForSync(targetDir);
      if (renameAndDeleteDiffs.length > 0) {
        // do the real sync work: deletion and rename
        syncDiff(renameAndDeleteDiffs, tfs, tmpDir);
      }
      return true;
    } catch (Exception e) {
      DistCp.LOG.warn("Failed to use snapshot diff for distcp", e);
      return false;
    } finally {
      deleteTargetTmpDir(tfs, tmpDir);
      // TODO: since we have tmp directory, we can support "undo" with failures
      // set the source path using the snapshot path
      context.setSourcePaths(Arrays.asList(getSnapshotPath(sourceDir,
          context.getToSnapshot())));
    }
  }
@Test
  public void testSyncWithCurrent() throws Exception {
    final DistCpOptions options = new DistCpOptions.Builder(
        Collections.singletonList(source), target)
        .withSyncFolder(true)
        .withUseDiff("s1", ".")
        .build();
    context = new DistCpContext(options);
    initData(source);
    initData(target);
    enableAndCreateFirstSnapshot();

    // make changes under source
    changeData(dfs, source);

    // do the sync
    sync();
    // make sure the source path is still unchanged
    Assert.assertEquals(source, context.getSourcePaths().get(0));
  }