Author: rinrab
Date: Thu May 8 14:19:32 2025
New Revision: 1925463
URL: http://svn.apache.org/viewvc?rev=1925463&view=rev
Log:
Add svn_client_patch2 function that accesses the patch file from an
APR file instead of using a local path.
* subversion/include/svn_client.h
(svn_client_patch2): New function.
(svn_client_patch): Deprecate.
* subversion/libsvn_client/deprecated.c
(svn_client_patch): Add and implement through svn_client_patch2().
* subversion/libsvn_client/patch.c
(apply_patches): Accept a file instead of a path and create a
svn_diff_patch_parser_t instead of opening a svn_patch_file_t.
(svn_client_patch): Update implementation to svn_client_patch2.
* subversion/svn/patch-cmd.c
(svn_cl__patch): Check and open the patch file manually, pass to
the new function, and close it then.
* subversion/tests/libsvn_client/client-test.c
(test_patch): Update patch api used.
See also a related discussion with myself on dev@ where this was
initiated: https://lists.apache.org/thread/p260hdrt5wx0tv6xs9l5nt3pvbzvnrv4
Modified:
subversion/trunk/subversion/include/svn_client.h
subversion/trunk/subversion/libsvn_client/deprecated.c
subversion/trunk/subversion/libsvn_client/patch.c
subversion/trunk/subversion/svn/patch-cmd.c
subversion/trunk/subversion/tests/libsvn_client/client-test.c
Modified: subversion/trunk/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=1925463&r1=1925462&r2=1925463&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Thu May 8 14:19:32 2025
@@ -7718,8 +7718,9 @@ typedef svn_error_t *(*svn_client_patch_
apr_pool_t *scratch_pool);
/**
- * Apply a unidiff patch that's located at absolute path
- * @a patch_abspath to the working copy directory at @a wc_dir_abspath.
+ * Apply a unidiff patch, described in @a apr_file which should have
+ * @c APR_READ and @c APR_BUFFERED capabilities to the working copy
+ * directory at @a wc_dir_abspath.
*
* This function makes a best-effort attempt at applying the patch.
* It might skip patch targets which cannot be patched (e.g. targets
@@ -7756,7 +7757,26 @@ typedef svn_error_t *(*svn_client_patch_
*
* Use @a scratch_pool for temporary allocations.
*
- * @since New in 1.7.
+ * @since New in 1.15.
+ */
+svn_error_t *
+svn_client_patch2(apr_file_t *apr_file,
+ const char *wc_dir_abspath,
+ svn_boolean_t dry_run,
+ int strip_count,
+ svn_boolean_t reverse,
+ svn_boolean_t ignore_whitespace,
+ svn_boolean_t remove_tempfiles,
+ svn_client_patch_func_t patch_func,
+ void *patch_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool);
+
+/**
+ * Similar to svn_client_patch2(), but accessing the patch by an absolute
+ * path.
+ *
+ * @deprecated Provided for backward compatibility with the 1.7 API.
*/
svn_error_t *
svn_client_patch(const char *patch_abspath,
Modified: subversion/trunk/subversion/libsvn_client/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/deprecated.c?rev=1925463&r1=1925462&r2=1925463&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_client/deprecated.c Thu May 8 14:19:32 2025
@@ -3290,3 +3290,46 @@ svn_client_upgrade(const char *path,
return svn_error_trace(svn_client_upgrade2(NULL, path, NULL, ctx,
NULL, scratch_pool));
}
+
+svn_error_t *
+svn_client_patch(const char *patch_abspath,
+ const char *wc_dir_abspath,
+ svn_boolean_t dry_run,
+ int strip_count,
+ svn_boolean_t reverse,
+ svn_boolean_t ignore_whitespace,
+ svn_boolean_t remove_tempfiles,
+ svn_client_patch_func_t patch_func,
+ void *patch_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ svn_node_kind_t kind;
+ apr_file_t *apr_file;
+
+ SVN_ERR(svn_io_check_path(patch_abspath, &kind, scratch_pool));
+ if (kind == svn_node_none)
+ return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("'%s' does not exist"),
+ svn_dirent_local_style(patch_abspath,
+ scratch_pool));
+ if (kind != svn_node_file)
+ return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("'%s' is not a file"),
+ svn_dirent_local_style(patch_abspath,
+ scratch_pool));
+
+ SVN_ERR(svn_io_file_open(&apr_file, patch_abspath,
+ APR_READ | APR_BUFFERED, APR_OS_DEFAULT,
+ scratch_pool));
+
+ SVN_ERR(svn_client_patch2(apr_file, wc_dir_abspath,
+ dry_run, strip_count, reverse,
+ ignore_whitespace, remove_tempfiles,
+ patch_func, patch_baton,
+ ctx, scratch_pool));
+
+ SVN_ERR(svn_io_file_close(apr_file, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
Modified: subversion/trunk/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/patch.c?rev=1925463&r1=1925462&r2=1925463&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/patch.c (original)
+++ subversion/trunk/subversion/libsvn_client/patch.c Thu May 8 14:19:32 2025
@@ -3613,8 +3613,8 @@ check_ancestor_delete(const char *delete
/* This function is the main entry point into the patch code. */
static svn_error_t *
-apply_patches(/* The path to the patch file. */
- const char *patch_abspath,
+apply_patches(/* The patch file. */
+ apr_file_t *apr_file,
/* The abspath to the working copy the patch should be applied to. */
const char *root_abspath,
/* Indicates whether we're doing a dry run. */
@@ -3636,11 +3636,10 @@ apply_patches(/* The path to the patch f
{
svn_patch_t *patch;
apr_pool_t *iterpool;
- svn_patch_file_t *patch_file;
+ svn_diff_patch_parser_t *patch_parser;
apr_array_header_t *targets_info;
- /* Try to open the patch file. */
- SVN_ERR(svn_diff_open_patch_file(&patch_file, patch_abspath, scratch_pool));
+ patch_parser = svn_diff_patch_parser_create(apr_file, scratch_pool);
/* Apply patches. */
targets_info = apr_array_make(scratch_pool, 0,
@@ -3653,9 +3652,9 @@ apply_patches(/* The path to the patch f
if (ctx->cancel_func)
SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
- SVN_ERR(svn_diff_parse_next_patch(&patch, patch_file,
- reverse, ignore_whitespace,
- iterpool, iterpool));
+ SVN_ERR(svn_diff_patch_parser_next(&patch, patch_parser,
+ reverse, ignore_whitespace,
+ iterpool, iterpool));
if (patch)
{
patch_target_t *target;
@@ -3720,24 +3719,23 @@ apply_patches(/* The path to the patch f
}
while (patch);
- SVN_ERR(svn_diff_close_patch_file(patch_file, iterpool));
svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
svn_error_t *
-svn_client_patch(const char *patch_abspath,
- const char *wc_dir_abspath,
- svn_boolean_t dry_run,
- int strip_count,
- svn_boolean_t reverse,
- svn_boolean_t ignore_whitespace,
- svn_boolean_t remove_tempfiles,
- svn_client_patch_func_t patch_func,
- void *patch_baton,
- svn_client_ctx_t *ctx,
- apr_pool_t *scratch_pool)
+svn_client_patch2(apr_file_t *apr_file,
+ const char *wc_dir_abspath,
+ svn_boolean_t dry_run,
+ int strip_count,
+ svn_boolean_t reverse,
+ svn_boolean_t ignore_whitespace,
+ svn_boolean_t remove_tempfiles,
+ svn_client_patch_func_t patch_func,
+ void *patch_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
{
svn_node_kind_t kind;
@@ -3751,18 +3749,6 @@ svn_client_patch(const char *patch_abspa
svn_dirent_local_style(wc_dir_abspath,
scratch_pool));
- SVN_ERR(svn_io_check_path(patch_abspath, &kind, scratch_pool));
- if (kind == svn_node_none)
- return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
- _("'%s' does not exist"),
- svn_dirent_local_style(patch_abspath,
- scratch_pool));
- if (kind != svn_node_file)
- return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
- _("'%s' is not a file"),
- svn_dirent_local_style(patch_abspath,
- scratch_pool));
-
SVN_ERR(svn_io_check_path(wc_dir_abspath, &kind, scratch_pool));
if (kind == svn_node_none)
return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
@@ -3776,7 +3762,7 @@ svn_client_patch(const char *patch_abspa
scratch_pool));
SVN_WC__CALL_WITH_WRITE_LOCK(
- apply_patches(patch_abspath, wc_dir_abspath, dry_run, strip_count,
+ apply_patches(apr_file, wc_dir_abspath, dry_run, strip_count,
reverse, ignore_whitespace, remove_tempfiles,
patch_func, patch_baton, ctx, scratch_pool),
ctx->wc_ctx, wc_dir_abspath, FALSE /* lock_anchor */, scratch_pool);
Modified: subversion/trunk/subversion/svn/patch-cmd.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/patch-cmd.c?rev=1925463&r1=1925462&r2=1925463&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/patch-cmd.c (original)
+++ subversion/trunk/subversion/svn/patch-cmd.c Thu May 8 14:19:32 2025
@@ -51,8 +51,10 @@ svn_cl__patch(apr_getopt_t *os,
apr_array_header_t *targets;
const char *abs_patch_path;
const char *patch_path;
+ apr_file_t *patch_file;
const char *abs_target_path;
const char *target_path;
+ svn_node_kind_t kind;
opt_state = ((svn_cl__cmd_baton_t *)baton)->opt_state;
ctx = ((svn_cl__cmd_baton_t *)baton)->ctx;
@@ -74,6 +76,19 @@ svn_cl__patch(apr_getopt_t *os,
SVN_ERR(svn_dirent_get_absolute(&abs_patch_path, patch_path, pool));
+ SVN_ERR(svn_io_check_path(abs_patch_path, &kind, pool));
+ if (kind == svn_node_none)
+ return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("'%s' does not exist"),
+ svn_dirent_local_style(abs_patch_path, pool));
+ if (kind != svn_node_file)
+ return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("'%s' is not a file"),
+ svn_dirent_local_style(abs_patch_path, pool));
+
+ SVN_ERR(svn_io_file_open(&patch_file, abs_patch_path,
+ APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool));
+
if (targets->nelts == 1)
target_path = ""; /* "" is the canonical form of "." */
else
@@ -84,12 +99,13 @@ svn_cl__patch(apr_getopt_t *os,
}
SVN_ERR(svn_dirent_get_absolute(&abs_target_path, target_path, pool));
- SVN_ERR(svn_client_patch(abs_patch_path, abs_target_path,
- opt_state->dry_run, opt_state->strip,
- opt_state->reverse_diff,
- opt_state->ignore_whitespace,
- TRUE, NULL, NULL, ctx, pool));
+ SVN_ERR(svn_client_patch2(patch_file, abs_target_path,
+ opt_state->dry_run, opt_state->strip,
+ opt_state->reverse_diff,
+ opt_state->ignore_whitespace,
+ TRUE, NULL, NULL, ctx, pool));
+ SVN_ERR(svn_io_file_close(patch_file, pool));
if (! opt_state->quiet)
SVN_ERR(svn_cl__notifier_print_conflict_stats(ctx->notify_baton2, pool));
Modified: subversion/trunk/subversion/tests/libsvn_client/client-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_client/client-test.c?rev=1925463&r1=1925462&r2=1925463&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_client/client-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_client/client-test.c Thu May 8 14:19:32 2025
@@ -348,6 +348,8 @@ test_patch(const svn_test_opts_t *opts,
const char *reject_tempfile_path;
const char *key;
int i;
+ apr_off_t off;
+
#define NL APR_EOL_STR
#define UNIDIFF_LINES 7
const char *unidiff_patch[UNIDIFF_LINES] = {
@@ -401,8 +403,8 @@ test_patch(const svn_test_opts_t *opts,
pool, svn_test_data_path("test-patch", pool),
"test-patch.diff", SVN_VA_NULL);
SVN_ERR(svn_io_file_open(&patch_file, patch_file_path,
- (APR_READ | APR_WRITE | APR_CREATE | APR_TRUNCATE),
- APR_OS_DEFAULT, pool));
+ (APR_READ | APR_WRITE | APR_CREATE | APR_TRUNCATE
+ | APR_BUFFERED), APR_OS_DEFAULT, pool));
for (i = 0; i < UNIDIFF_LINES; i++)
{
apr_size_t len = strlen(unidiff_patch[i]);
@@ -415,9 +417,12 @@ test_patch(const svn_test_opts_t *opts,
pcb.patched_tempfiles = apr_hash_make(pool);
pcb.reject_tempfiles = apr_hash_make(pool);
pcb.state_pool = pool;
- SVN_ERR(svn_client_patch(patch_file_path, wc_path, FALSE, 0, FALSE,
- FALSE, FALSE, patch_collection_func, &pcb,
- ctx, pool));
+
+ off = 0;
+ SVN_ERR(svn_io_file_seek(patch_file, APR_SET, &off, pool));
+ SVN_ERR(svn_client_patch2(patch_file, wc_path, FALSE, 0, FALSE,
+ FALSE, FALSE, patch_collection_func, &pcb,
+ ctx, pool));
SVN_ERR(svn_io_file_close(patch_file, pool));
SVN_TEST_ASSERT(apr_hash_count(pcb.patched_tempfiles) == 1);
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.