You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2019/01/07 20:45:55 UTC
svn commit: r1850689 - in /subversion/trunk/subversion:
include/private/svn_client_private.h libsvn_client/client.h
libsvn_client/commit.c libsvn_client/commit_util.c libsvn_client/wc_editor.c
Author: julianfoad
Date: Mon Jan 7 20:45:55 2019
New Revision: 1850689
URL: http://svn.apache.org/viewvc?rev=1850689&view=rev
Log:
Improvements to the 'WC editor' for issue #4786.
* subversion/include/private/svn_client_private.h
(svn_client__wc_editor): Specify the form of path arguments to the editor.
(svn_client__wc_replay): Same, and add a WC abspath argument.
* subversion/libsvn_client/commit.c
(svn_client__wc_replay): Add a WC abspath argument, and make all editor
paths relative to (the URL of) that path.
* subversion/libsvn_client/client.h,
subversion/libsvn_client/commit_util.c
(svn_client__condense_commit_items2): New.
* subversion/libsvn_client/wc_editor.c
(file_baton_t,
file_textdelta,
file_close): Add support for making a text-delta against a non-empty
base.
Modified:
subversion/trunk/subversion/include/private/svn_client_private.h
subversion/trunk/subversion/libsvn_client/client.h
subversion/trunk/subversion/libsvn_client/commit.c
subversion/trunk/subversion/libsvn_client/commit_util.c
subversion/trunk/subversion/libsvn_client/wc_editor.c
Modified: subversion/trunk/subversion/include/private/svn_client_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_client_private.h?rev=1850689&r1=1850688&r2=1850689&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_client_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_client_private.h Mon Jan 7 20:45:55 2019
@@ -445,6 +445,10 @@ svn_client__repos_to_wc_copy_by_editor(s
* Return an editor in @a *editor_p, @a *edit_baton_p that will apply
* local modifications to the WC subdirectory at @a dst_abspath.
*
+ * The @a path arguments to the editor methods shall be local WC paths,
+ * relative to @a dst_abspath. The @a copyfrom_path arguments to the
+ * editor methods shall be URLs.
+ *
* Send notifications via @a notify_func / @a notify_baton.
*
* RA_SESSION is used to fetch the original content for copies.
@@ -488,7 +492,17 @@ svn_client__wc_editor_internal(const svn
*
* Committable changes are found in TARGETS:DEPTH:CHANGELISTS.
*
- * Send the changes to EDITOR:EDIT_BATON.
+ * Send the changes to @a editor:@a edit_baton. The @a path arguments
+ * to the editor methods are URL-paths relative to the URL of
+ * @a src_wc_abspath.
+ *
+ * ### We will presumably need to change this so that the @a path
+ * arguments to the editor will be local WC relpaths, in order
+ * to handle switched paths.
+ *
+ * The @a copyfrom_path arguments to the editor methods are URLs. As the
+ * WC does not store copied-from-foreign-repository metadata, the URL will
+ * be in the same repository as the URL of its parent path.
*
* Compared with svn_client__do_commit(), this (like svn_client_commit6)
* handles:
@@ -506,7 +520,8 @@ svn_client__wc_editor_internal(const svn
* - removing locks and changelists in WC
*/
svn_error_t *
-svn_client__wc_replay(const apr_array_header_t *targets,
+svn_client__wc_replay(const char *src_wc_abspath,
+ const apr_array_header_t *targets,
svn_depth_t depth,
const apr_array_header_t *changelists,
const svn_delta_editor_t *editor,
Modified: subversion/trunk/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/client.h?rev=1850689&r1=1850688&r2=1850689&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/client.h (original)
+++ subversion/trunk/subversion/libsvn_client/client.h Mon Jan 7 20:45:55 2019
@@ -870,6 +870,18 @@ svn_client__condense_commit_items(const
apr_array_header_t *commit_items,
apr_pool_t *pool);
+/* Rewrite the COMMIT_ITEMS array to be sorted by URL.
+ Rewrite the items' URLs to be relative to BASE_URL.
+
+ COMMIT_ITEMS is an array of (svn_client_commit_item3_t *) items.
+
+ Afterwards, some of the items in COMMIT_ITEMS may contain data
+ allocated in POOL. */
+svn_error_t *
+svn_client__condense_commit_items2(const char *base_url,
+ apr_array_header_t *commit_items,
+ apr_pool_t *pool);
+
/* Commit the items in the COMMIT_ITEMS array using EDITOR/EDIT_BATON
to describe the committed local mods. Prior to this call,
COMMIT_ITEMS should have been run through (and BASE_URL generated
Modified: subversion/trunk/subversion/libsvn_client/commit.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/commit.c?rev=1850689&r1=1850688&r2=1850689&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/commit.c (original)
+++ subversion/trunk/subversion/libsvn_client/commit.c Mon Jan 7 20:45:55 2019
@@ -553,7 +553,8 @@ harvest_committables(apr_array_header_t
}
svn_error_t *
-svn_client__wc_replay(const apr_array_header_t *targets,
+svn_client__wc_replay(const char *src_wc_abspath,
+ const apr_array_header_t *targets,
svn_depth_t depth,
const apr_array_header_t *changelists,
const svn_delta_editor_t *editor,
@@ -565,7 +566,9 @@ svn_client__wc_replay(const apr_array_he
apr_array_header_t *rel_targets;
apr_hash_t *lock_tokens;
apr_array_header_t *commit_items;
+ svn_client__pathrev_t *base;
const char *base_url;
+ svn_wc_notify_func2_t saved_notify_func;
/* Condense the target list. This makes all targets absolute. */
SVN_ERR(svn_dirent_condense_targets(&base_abspath, &rel_targets, targets,
@@ -592,15 +595,25 @@ svn_client__wc_replay(const apr_array_he
FALSE /*just_locked*/,
changelists,
ctx, pool, pool));
+ if (!commit_items)
+ {
+ return SVN_NO_ERROR;
+ }
+
+ SVN_ERR(svn_client__wc_node_get_base(&base,
+ src_wc_abspath, ctx->wc_ctx, pool, pool));
+ base_url = base->url;
+ /* Sort our COMMIT_ITEMS by URL and find their relative URL-paths. */
+ SVN_ERR(svn_client__condense_commit_items2(base_url, commit_items, pool));
- /* Sort and condense our COMMIT_ITEMS. */
- SVN_ERR(svn_client__condense_commit_items(&base_url, commit_items, pool));
-
+ saved_notify_func = ctx->notify_func2;
ctx->notify_func2 = NULL;
+ /* BASE_URL is only used here in notifications & errors */
SVN_ERR(svn_client__do_commit(base_url, commit_items,
editor, edit_baton,
NULL /*notify_prefix*/, NULL /*sha1_checksums*/,
ctx, pool, pool));
+ ctx->notify_func2 = saved_notify_func;
return SVN_NO_ERROR;
}
Modified: subversion/trunk/subversion/libsvn_client/commit_util.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/commit_util.c?rev=1850689&r1=1850688&r2=1850689&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/commit_util.c (original)
+++ subversion/trunk/subversion/libsvn_client/commit_util.c Mon Jan 7 20:45:55 2019
@@ -1392,6 +1392,29 @@ sort_commit_item_urls(const void *a, con
}
+svn_error_t *
+svn_client__condense_commit_items2(const char *base_url,
+ apr_array_header_t *commit_items,
+ apr_pool_t *pool)
+{
+ apr_array_header_t *ci = commit_items; /* convenience */
+ int i;
+
+ /* Sort our commit items by their URLs. */
+ svn_sort__array(ci, sort_commit_item_urls);
+
+ /* Hack BASE_URL off each URL; store the result as session_relpath. */
+ for (i = 0; i < ci->nelts; i++)
+ {
+ svn_client_commit_item3_t *this_item
+ = APR_ARRAY_IDX(ci, i, svn_client_commit_item3_t *);
+
+ this_item->session_relpath = svn_uri_skip_ancestor(base_url,
+ this_item->url, pool);
+ }
+
+ return SVN_NO_ERROR;
+}
svn_error_t *
svn_client__condense_commit_items(const char **base_url,
Modified: subversion/trunk/subversion/libsvn_client/wc_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/wc_editor.c?rev=1850689&r1=1850688&r2=1850689&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/wc_editor.c (original)
+++ subversion/trunk/subversion/libsvn_client/wc_editor.c Mon Jan 7 20:45:55 2019
@@ -1,5 +1,5 @@
/*
- * copy_foreign.c: copy from other repository support.
+ * wc_editor.c: editing the local modifications in the WC.
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
@@ -51,8 +51,6 @@
* TODO:
* - tests
* - use for all existing scenarios ('svn add', 'svn propset', etc.)
- * - copy-from (half done: in dir_add only, untested)
- * - text-delta
* - Instead of 'root_dir_add' option, probably the driver should anchor
* at the parent dir.
* - Instead of 'ignore_mergeinfo' option, implement that as a wrapper.
@@ -350,7 +348,7 @@ struct file_baton_t
svn_boolean_t created; /* already under version control in the WC */
apr_hash_t *properties;
- svn_boolean_t writing;
+ const char *writing_file;
unsigned char digest[APR_MD5_DIGESTSIZE];
const char *tmp_path;
@@ -473,15 +471,28 @@ file_textdelta(void *file_baton,
void **handler_baton)
{
struct file_baton_t *fb = file_baton;
+ const char *target_dir = svn_dirent_dirname(fb->local_abspath, fb->pool);
+ svn_error_t *err;
+ svn_stream_t *source;
svn_stream_t *target;
- SVN_ERR_ASSERT(! fb->writing);
+ SVN_ERR_ASSERT(! fb->writing_file);
- SVN_ERR(svn_stream_open_writable(&target, fb->local_abspath, fb->pool,
- fb->pool));
+ err = svn_stream_open_readonly(&source, fb->local_abspath,
+ fb->pool, fb->pool);
+ if (err && APR_STATUS_IS_ENOENT(err->apr_err))
+ {
+ svn_error_clear(err);
+ source = svn_stream_empty(fb->pool);
+ }
+ else
+ SVN_ERR(err);
- fb->writing = TRUE;
- svn_txdelta_apply(svn_stream_empty(fb->pool) /* source */,
+ SVN_ERR(svn_stream_open_unique(&target, &fb->writing_file,
+ target_dir, svn_io_file_del_none,
+ fb->pool, fb->pool));
+
+ svn_txdelta_apply(source,
target,
fb->digest,
fb->local_abspath,
@@ -523,6 +534,10 @@ file_close(void *file_baton,
struct file_baton_t *fb = file_baton;
struct dir_baton_t *pb = fb->pb;
+ if (fb->writing_file)
+ SVN_ERR(svn_io_file_rename2(fb->writing_file, fb->local_abspath,
+ FALSE /*flush*/, scratch_pool));
+
if (text_checksum)
{
svn_checksum_t *expected_checksum;