> However, I noticed a little problem in the implementation of patching; The
> svn_client_patch() function accesses the patchfile by an absolute path
> instead of a handle to a file. This follows that the file will be opened
> twice. Is it possible to modify it, so the svn_client_patch() function
> will accept apr_file_t or a svn_stream_t instead of an absolute path to
> this file?
Hi,
I made a work-in-progress patch in which svn_client_patch [now
svn_client_patch2] function will read the patch, which has already
been opened at the top of the callstack.
Attaching the patch to the email as 'svn-patch-by-file-wip-v1.patch.txt'.
What do you think, should I continue this work?
PS: this is a patch of svn-patch :-)
--
Timofei Zhakov
Index: subversion/include/svn_client.h
===================================================================
--- subversion/include/svn_client.h (revision 1922465)
+++ subversion/include/svn_client.h (working copy)
@@ -7756,9 +7756,29 @@
*
* 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,
const char *wc_dir_abspath,
svn_boolean_t dry_run,
Index: subversion/include/svn_diff.h
===================================================================
--- subversion/include/svn_diff.h (revision 1922465)
+++ subversion/include/svn_diff.h (working copy)
@@ -1333,11 +1333,24 @@
* @since New in 1.7. */
typedef struct svn_patch_file_t svn_patch_file_t;
-/** Open @a patch_file at @a local_abspath.
+/**
+ * Open @a patch_file at @a local_abspath.
* Allocate @a patch_file in @a result_pool.
*
- * @since New in 1.7. */
+ * @since New in 1.15.
+ */
svn_error_t *
+svn_diff_open_patch_file2(svn_patch_file_t **patch_file,
+ apr_file_t *file,
+ apr_pool_t *result_pool);
+
+/**
+ * Similar to svn_diff_open_patch_file2(), but accessing the patch by an
+ * absolute path.
+ *
+ * @deprecated Provided for backward compatibility with the 1.7 API.
+ */
+svn_error_t *
svn_diff_open_patch_file(svn_patch_file_t **patch_file,
const char *local_abspath,
apr_pool_t *result_pool);
@@ -1365,7 +1378,9 @@
* Use @a scratch_pool for all temporary allocations.
*
* @since New in 1.7.
+ * @deprecated Provided for backward compatibility with the 1.7 API.
*/
+SVN_DEPRECATED
svn_error_t *
svn_diff_close_patch_file(svn_patch_file_t *patch_file,
apr_pool_t *scratch_pool);
Index: subversion/libsvn_client/deprecated.c
===================================================================
--- subversion/libsvn_client/deprecated.c (revision 1922465)
+++ subversion/libsvn_client/deprecated.c (working copy)
@@ -3290,3 +3290,42 @@
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));
+
+ return svn_error_trace(svn_client_patch2(apr_file, wc_dir_abspath,
+ dry_run, strip_count, reverse,
+ ignore_whitespace, remove_tempfiles,
+ patch_func, patch_baton,
+ ctx, scratch_pool));
+}
Index: subversion/libsvn_client/patch.c
===================================================================
--- subversion/libsvn_client/patch.c (revision 1922465)
+++ subversion/libsvn_client/patch.c (working copy)
@@ -3613,8 +3613,8 @@
/* 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. */
@@ -3640,7 +3640,7 @@
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));
+ SVN_ERR(svn_diff_open_patch_file2(&patch_file, apr_file, scratch_pool));
/* Apply patches. */
targets_info = apr_array_make(scratch_pool, 0,
@@ -3727,17 +3727,17 @@
}
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 +3751,6 @@
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 +3764,7 @@
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);
Index: subversion/libsvn_diff/deprecated.c
===================================================================
--- subversion/libsvn_diff/deprecated.c (revision 1922465)
+++ subversion/libsvn_diff/deprecated.c (working copy)
@@ -462,3 +462,19 @@
NULL, NULL,
pool));
}
+
+svn_error_t *
+svn_diff_open_patch_file(svn_patch_file_t **patch_file,
+ const char *local_abspath,
+ apr_pool_t *result_pool)
+{
+ apr_file_t *file;
+
+ SVN_ERR(svn_io_file_open(&file, local_abspath,
+ APR_READ | APR_BUFFERED, APR_OS_DEFAULT,
+ result_pool));
+
+ return svn_error_trace(svn_diff_open_patch_file2(patch_file, file,
+ result_pool));
+
+}
Index: subversion/libsvn_diff/parse-diff.c
===================================================================
--- subversion/libsvn_diff/parse-diff.c (revision 1922465)
+++ subversion/libsvn_diff/parse-diff.c (working copy)
@@ -1957,16 +1957,14 @@
};
svn_error_t *
-svn_diff_open_patch_file(svn_patch_file_t **patch_file,
- const char *local_abspath,
- apr_pool_t *result_pool)
+svn_diff_open_patch_file2(svn_patch_file_t **patch_file,
+ apr_file_t *file,
+ apr_pool_t *result_pool)
{
svn_patch_file_t *p;
p = apr_palloc(result_pool, sizeof(*p));
- SVN_ERR(svn_io_file_open(&p->apr_file, local_abspath,
- APR_READ | APR_BUFFERED, APR_OS_DEFAULT,
- result_pool));
+ p->apr_file = file;
p->next_patch_offset = 0;
*patch_file = p;