Alien-SVN

 view release on metacpan or  search on metacpan

src/subversion/subversion/libsvn_client/patch.c  view on Meta::CPAN


      prop_target = svn__apr_hash_index_val(hash_index);

      for (i = 0; i < prop_target->content->hunks->nelts; i++)
        {
          hunk_info_t *hi;

          svn_pool_clear(iterpool);

          hi = APR_ARRAY_IDX(prop_target->content->hunks, i,
                             hunk_info_t *);
          if (hi->already_applied)
            continue;
          else if (hi->rejected)
            SVN_ERR(reject_hunk(target, prop_target->content, hi->hunk,
                                prop_target->name,
                                iterpool));
          else
            SVN_ERR(apply_hunk(target, prop_target->content, hi,
                               prop_target->name,
                               iterpool));
        }

        if (prop_target->content->existed)
          {
            /* Copy any remaining lines to target. */
            SVN_ERR(copy_lines_to_target(prop_target->content, 0,
                                         scratch_pool));
            if (! prop_target->content->eof)
              {
                /* We could not copy the entire target property to the
                 * temporary file, and would truncate the target if we
                 * copied the temporary file on top of it. Skip this target.  */
                target->skipped = TRUE;
              }
          }
      }

  svn_pool_destroy(iterpool);

  if (!target->is_symlink)
    {
      /* Now close files we don't need any longer to get their contents
       * flushed to disk.
       * But we're not closing the reject file -- it still needed and
       * will be closed later in write_out_rejected_hunks(). */
      if (target->kind_on_disk == svn_node_file)
        SVN_ERR(svn_io_file_close(target->file, scratch_pool));

      SVN_ERR(svn_io_file_close(target->patched_file, scratch_pool));
    }

  if (! target->skipped)
    {
      apr_finfo_t working_file;
      apr_finfo_t patched_file;

      /* Get sizes of the patched temporary file and the working file.
       * We'll need those to figure out whether we should delete the
       * patched file. */
      SVN_ERR(svn_io_stat(&patched_file, target->patched_path,
                          APR_FINFO_SIZE | APR_FINFO_LINK, scratch_pool));
      if (target->kind_on_disk == svn_node_file)
        SVN_ERR(svn_io_stat(&working_file, target->local_abspath,
                            APR_FINFO_SIZE | APR_FINFO_LINK, scratch_pool));
      else
        working_file.size = 0;

      if (patched_file.size == 0 && working_file.size > 0)
        {
          /* If a unidiff removes all lines from a file, that usually
           * means deletion, so we can confidently schedule the target
           * for deletion. In the rare case where the unidiff was really
           * meant to replace a file with an empty one, this may not
           * be desirable. But the deletion can easily be reverted and
           * creating an empty file manually is not exactly hard either. */
          target->deleted = (target->db_kind == svn_node_file);
        }
      else if (patched_file.size == 0 && working_file.size == 0)
        {
          /* The target was empty or non-existent to begin with
           * and no content was changed by patching.
           * Report this as skipped if it didn't exist, unless in the special
           * case of adding an empty file which has properties set on it or
           * adding an empty file with a 'git diff' */
          if (target->kind_on_disk == svn_node_none
              && ! target->has_prop_changes
              && ! target->added)
            target->skipped = TRUE;
        }
      else if (patched_file.size > 0 && working_file.size == 0)
        {
          /* The patch has created a file. */
          if (target->locally_deleted)
            target->replaced = TRUE;
          else if (target->db_kind == svn_node_none)
            target->added = TRUE;
        }
    }

  *patch_target = target;

  return SVN_NO_ERROR;
}

/* Try to create missing parent directories for TARGET in the working copy
 * rooted at ABS_WC_PATH, and add the parents to version control.
 * If the parents cannot be created, mark the target as skipped.
 * Use client context CTX. If DRY_RUN is true, do not create missing
 * parents but issue notifications only.
 * Use SCRATCH_POOL for temporary allocations. */
static svn_error_t *
create_missing_parents(patch_target_t *target,
                       const char *abs_wc_path,
                       svn_client_ctx_t *ctx,
                       svn_boolean_t dry_run,
                       apr_pool_t *scratch_pool)
{
  const char *local_abspath;
  apr_array_header_t *components;
  int present_components;
  int i;
  apr_pool_t *iterpool;



( run in 0.551 second using v1.01-cache-2.11-cpan-39bf76dae61 )