private void moveTaskOutputs(final Configuration conf, Path srcf, Path srcDir,
      Path destDir, boolean immutable) throws IOException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("moveTaskOutputs "
          + srcf + " from: " + srcDir + " to: " + destDir + " immutable: " + immutable);
    }

    if (dynamicPartitioningUsed) {
      immutable = true; // Making sure we treat dynamic partitioning jobs as if they were immutable.
    }

    final FileSystem srcFs = srcf.getFileSystem(conf);
    final FileSystem destFs = destDir.getFileSystem(conf);
    final boolean canRename = srcFs.getUri().equals(destFs.getUri());

    if (destFs.exists(destDir) && !destFs.getFileStatus(destDir).isDirectory()) {
      throw new HCatException(ErrorType.ERROR_MOVE_FAILED, "Destination is not directory " + destDir);
    }

    LinkedList<Pair<Path, Path>> moves = new LinkedList<>();
    if (customDynamicLocationUsed) {
      if (immutable && destFs.exists(destDir)
          && !org.apache.hadoop.hive.metastore.utils.FileUtils.isDirEmpty(destFs, destDir)) {
        throw new HCatException(ErrorType.ERROR_DUPLICATE_PARTITION,
            "Data already exists in " + destDir
                + ", duplicate publish not possible.");
      }
      moves.add(Pair.of(srcf, destDir));
    } else {
      Queue<FileStatus> srcQ = new LinkedList<>();
      FileStatus[] contents = srcFs.listStatus(srcf, HIDDEN_FILES_PATH_FILTER);
      if (contents.length == 0) {
        // nothing to move
        return;
      }
      Collections.addAll(srcQ, contents);

      while (!srcQ.isEmpty()) {
        FileStatus srcStatus = srcQ.remove();
        Path srcF = srcStatus.getPath();
        final Path finalOutputPath = getFinalPath(destFs, srcF, srcDir, destDir, immutable);
        if (immutable && destFs.exists(finalOutputPath)
            && !org.apache.hadoop.hive.metastore.utils.FileUtils.isDirEmpty(destFs, finalOutputPath)) {
          if (partitionsDiscoveredByPath.containsKey(srcF.toString())) {
            throw new HCatException(ErrorType.ERROR_DUPLICATE_PARTITION,
                "Data already exists in " + finalOutputPath + ", duplicate publish not possible.");
          }
          // parent directory may exist for multi-partitions, check lower level partitions
          Collections.addAll(srcQ, srcFs.listStatus(srcF, HIDDEN_FILES_PATH_FILTER));
        } else if (srcStatus.isDirectory()) {
          if (canRename && dynamicPartitioningUsed) {
            // If it is partition, move the partition directory instead of each file.
            moves.add(Pair.of(srcF, finalOutputPath));
          } else {
            Collections.addAll(srcQ, srcFs.listStatus(srcF, HIDDEN_FILES_PATH_FILTER));
          }
        } else {
          moves.add(Pair.of(srcF, finalOutputPath));
        }
      }
    }

    bulkMoveFiles(conf, srcFs, destFs, moves);
  }
Move task output from the temp directory to the final location
@param srcf the file to move
@param srcDir the source directory
@param destDir the target directory
@param immutable - whether table is immutable.
@throws java.io.IOException
hcatalog/core/src/main/java/org/apache/hive/hcatalog/mapreduce/FileOutputCommitterContainer.java