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 )