Return-Path: X-Original-To: apmail-subversion-commits-archive@minotaur.apache.org Delivered-To: apmail-subversion-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 6D05111D20 for ; Tue, 9 Sep 2014 17:30:39 +0000 (UTC) Received: (qmail 90211 invoked by uid 500); 9 Sep 2014 17:30:39 -0000 Delivered-To: apmail-subversion-commits-archive@subversion.apache.org Received: (qmail 90184 invoked by uid 500); 9 Sep 2014 17:30:39 -0000 Mailing-List: contact commits-help@subversion.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@subversion.apache.org Delivered-To: mailing list commits@subversion.apache.org Received: (qmail 90174 invoked by uid 99); 9 Sep 2014 17:30:39 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 09 Sep 2014 17:30:39 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 09 Sep 2014 17:30:36 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id BAC0123888D2; Tue, 9 Sep 2014 17:30:16 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1623860 - in /subversion/branches/move-tracking-2: build.conf subversion/include/private/svn_ra_private.h subversion/libsvn_ra/ra_loader.c subversion/svnmover/ subversion/svnmover/svnmover.c Date: Tue, 09 Sep 2014 17:30:16 -0000 To: commits@subversion.apache.org From: julianfoad@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20140909173016.BAC0123888D2@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: julianfoad Date: Tue Sep 9 17:30:16 2014 New Revision: 1623860 URL: http://svn.apache.org/r1623860 Log: On the 'move-tracking-2' branch: add a 'svnmover' utility program similar to 'svnmucc', for making move-aware commits. Added: subversion/branches/move-tracking-2/subversion/svnmover/ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c - copied, changed from r1622214, subversion/branches/move-tracking-2/subversion/svnmucc/svnmucc.c Modified: subversion/branches/move-tracking-2/build.conf subversion/branches/move-tracking-2/subversion/include/private/svn_ra_private.h subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.c Modified: subversion/branches/move-tracking-2/build.conf URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/build.conf?rev=1623860&r1=1623859&r2=1623860&view=diff ============================================================================== --- subversion/branches/move-tracking-2/build.conf (original) +++ subversion/branches/move-tracking-2/build.conf Tue Sep 9 17:30:16 2014 @@ -210,6 +210,14 @@ libs = libsvn_client libsvn_ra libsvn_re install = bin manpages = subversion/svnrdump/svnrdump.1 +[svnmover] +description = Subversion Mover Command Client +type = exe +path = subversion/svnmover +libs = libsvn_client libsvn_ra libsvn_subr libsvn_delta apriconv apr +install = bin +manpages = subversion/svnmover/svnmover.1 + [svnmucc] description = Subversion Multiple URL Command Client type = exe @@ -1454,7 +1462,7 @@ libs = libsvn_fs_base libsvn_fs_fs libsv [__ALL__] type = project path = build/win32 -libs = svn svnadmin svndumpfilter svnlook svnmucc svnserve svnrdump svnsync +libs = svn svnadmin svndumpfilter svnlook svnmover svnmucc svnserve svnrdump svnsync svnversion mod_authz_svn mod_dav_svn mod_dontdothat svnauthz svnauthz-validate svnraisetreeconflict Modified: subversion/branches/move-tracking-2/subversion/include/private/svn_ra_private.h URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_ra_private.h?rev=1623860&r1=1623859&r2=1623860&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/include/private/svn_ra_private.h (original) +++ subversion/branches/move-tracking-2/subversion/include/private/svn_ra_private.h Tue Sep 9 17:30:16 2014 @@ -34,6 +34,7 @@ #include "svn_delta.h" #include "svn_editor.h" #include "svn_io.h" +#include "private/svn_editor3.h" #ifdef __cplusplus extern "C" { @@ -280,6 +281,16 @@ svn_ra__replay_ev2(svn_ra_session_t *ses svn_editor_t *editor, apr_pool_t *scratch_pool); +svn_error_t * +svn_ra_get_commit_editor_ev3(svn_ra_session_t *session, + svn_editor3_t **editor, + apr_hash_t *revprop_table, + svn_commit_callback2_t commit_callback, + void *commit_baton, + apr_hash_t *lock_tokens, + svn_boolean_t keep_locks, + apr_pool_t *pool); + #ifdef __cplusplus } Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.c?rev=1623860&r1=1623859&r2=1623860&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.c (original) +++ subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.c Tue Sep 9 17:30:16 2014 @@ -808,6 +808,52 @@ fetch(svn_node_kind_t *kind_p, return SVN_NO_ERROR; } +svn_error_t *svn_ra_get_commit_editor_ev3(svn_ra_session_t *session, + svn_editor3_t **editor, + apr_hash_t *revprop_table, + svn_commit_callback2_t commit_callback, + void *commit_baton, + apr_hash_t *lock_tokens, + svn_boolean_t keep_locks, + apr_pool_t *pool) +{ + const svn_delta_editor_t *deditor; + void *dedit_baton; + svn_editor3__shim_connector_t *shim_connector; + + remap_commit_callback(&commit_callback, &commit_baton, + session, commit_callback, commit_baton, + pool); + + SVN_ERR(session->vtable->get_commit_editor(session, &deditor, &dedit_baton, + revprop_table, + commit_callback, commit_baton, + lock_tokens, keep_locks, pool)); + + /* Convert to Ev3 */ + { + const char *repos_root_url, *session_url, *base_relpath; + struct fb_baton *fbb = apr_palloc(pool, sizeof(*fbb)); + + SVN_ERR(svn_ra_get_repos_root2(session, &repos_root_url, pool)); + SVN_ERR(svn_ra_get_session_url(session, &session_url, pool)); + base_relpath = svn_uri_skip_ancestor(repos_root_url, session_url, pool); + SVN_ERR(svn_ra_dup_session(&fbb->session, session, repos_root_url, pool, pool)); + fbb->session_path = base_relpath; + fbb->repos_root_url = repos_root_url; + SVN_ERR(svn_delta__ev3_from_delta_for_commit( + editor, + &shim_connector, + deditor, dedit_baton, + repos_root_url, base_relpath, + fetch, fbb, + NULL, NULL /*cancel*/, + pool, pool)); + } + + return SVN_NO_ERROR; +} + svn_error_t *svn_ra_get_commit_editor3(svn_ra_session_t *session, const svn_delta_editor_t **editor, void **edit_baton, Copied: subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c (from r1622214, subversion/branches/move-tracking-2/subversion/svnmucc/svnmucc.c) URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c?p2=subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c&p1=subversion/branches/move-tracking-2/subversion/svnmucc/svnmucc.c&r1=1622214&r2=1623860&rev=1623860&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/svnmucc/svnmucc.c (original) +++ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c Tue Sep 9 17:30:16 2014 @@ -1,5 +1,5 @@ /* - * svnmucc.c: Subversion Multiple URL Client + * svnmover.c: Subversion Multiple URL Client * * ==================================================================== * Licensed to the Apache Software Foundation (ASF) under one @@ -31,7 +31,7 @@ tree of operation structures. The tree of operation structures is used to drive an RA commit editor to produce a single commit. - To build this client, type 'make svnmucc' from the root of your + To build this client, type 'make svnmover' from the root of your Subversion source directory. */ @@ -57,6 +57,8 @@ #include "private/svn_cmdline_private.h" #include "private/svn_subr_private.h" +#include "private/svn_editor3.h" +#include "private/svn_ra_private.h" /* Version compatibility check */ static svn_error_t * @@ -74,6 +76,130 @@ check_lib_versions(void) return svn_ver_check_list2(&my_version, checklist, svn_ver_equal); } +/* Construct a peg-path-rev */ +static svn_editor3_peg_path_t +pathrev(const char *repos_relpath, svn_revnum_t revision) +{ + svn_editor3_peg_path_t p; + + p.rev = revision; + p.relpath = repos_relpath; + return p; +} + +/* Construct a txn-path-rev */ +static svn_editor3_txn_path_t +txn_path(const char *repos_relpath, svn_revnum_t revision, + const char *created_relpath) +{ + svn_editor3_txn_path_t p; + + p.peg.rev = revision; + p.peg.relpath = repos_relpath; + p.relpath = created_relpath; + return p; +} + +typedef struct mtcc_t +{ + apr_pool_t *pool; + const char *repos_root_url; + /*const char *anchor_repos_relpath;*/ + svn_revnum_t head_revision; + svn_revnum_t base_revision; + + svn_ra_session_t *ra_session; + svn_editor3_t *editor; + svn_client_ctx_t *ctx; +} mtcc_t; + +static svn_error_t * +mtcc_create(mtcc_t **mtcc_p, + const char *anchor_url, + svn_revnum_t base_revision, + apr_hash_t *revprops, + svn_commit_callback2_t commit_callback, + void *commit_baton, + svn_client_ctx_t *ctx, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + apr_pool_t *mtcc_pool = svn_pool_create(result_pool); + mtcc_t *mtcc = apr_pcalloc(mtcc_pool, sizeof(*mtcc)); + + mtcc->pool = mtcc_pool; + mtcc->ctx = ctx; + + SVN_ERR(svn_client_open_ra_session2(&mtcc->ra_session, anchor_url, + NULL /* wri_abspath */, ctx, + mtcc_pool, scratch_pool)); + + SVN_ERR(svn_ra_get_repos_root2(mtcc->ra_session, &mtcc->repos_root_url, + result_pool)); + SVN_ERR(svn_ra_get_latest_revnum(mtcc->ra_session, &mtcc->head_revision, + scratch_pool)); + + if (! SVN_IS_VALID_REVNUM(base_revision)) + mtcc->base_revision = mtcc->head_revision; + else if (base_revision > mtcc->head_revision) + return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL, + _("No such revision %ld (HEAD is %ld)"), + base_revision, mtcc->head_revision); + else + mtcc->base_revision = base_revision; + + SVN_ERR(svn_ra_get_commit_editor_ev3(mtcc->ra_session, &mtcc->editor, + revprops, + commit_callback, commit_baton, + NULL /*lock_tokens*/, FALSE /*keep_locks*/, + result_pool)); + *mtcc_p = mtcc; + return SVN_NO_ERROR; +} + +static svn_error_t * +mtcc_commit(mtcc_t *mtcc, + apr_pool_t *scratch_pool) +{ + svn_error_t *err; + +#if 0 + /* No changes -> no revision. Easy out */ + if (MTCC_UNMODIFIED(mtcc)) + { + svn_editor3_abort(mtcc->editor); + svn_pool_destroy(mtcc->pool); + return SVN_NO_ERROR; + } +#endif + +#if 0 + const char *session_url; + + SVN_ERR(svn_ra_get_session_url(mtcc->ra_session, &session_url, scratch_pool)); + + if (mtcc->root_op->kind != OP_OPEN_DIR) + { + const char *name; + + svn_uri_split(&session_url, &name, session_url, scratch_pool); + + if (*name) + { + SVN_ERR(mtcc_reparent(session_url, mtcc, scratch_pool)); + + SVN_ERR(svn_ra_reparent(mtcc->ra_session, session_url, scratch_pool)); + } + } +#endif + + err = svn_editor3_complete(mtcc->editor); + + svn_pool_destroy(mtcc->pool); + + return svn_error_trace(err); +} + static svn_error_t * commit_callback(const svn_commit_info_t *commit_info, void *baton, @@ -91,21 +217,10 @@ typedef enum action_code_t { ACTION_MV, ACTION_MKDIR, ACTION_CP, - ACTION_PROPSET, - ACTION_PROPSETF, - ACTION_PROPDEL, ACTION_PUT, ACTION_RM } action_code_t; -/* Return the portion of URL that is relative to ANCHOR (URI-decoded). */ -static const char * -subtract_anchor(const char *anchor, const char *url, apr_pool_t *pool) -{ - return svn_uri_skip_ancestor(anchor, url, pool); -} - - struct action { action_code_t action; @@ -119,75 +234,96 @@ struct action { * cp source target * put target source * rm target (null) - * propset target (null) */ const char *path[2]; - - /* property name/value */ - const char *prop_name; - const svn_string_t *prop_value; }; static svn_error_t * execute(const apr_array_header_t *actions, - const char *anchor, + const char *anchor_url, + const char *log_msg, apr_hash_t *revprops, svn_revnum_t base_revision, svn_client_ctx_t *ctx, apr_pool_t *pool) { - svn_client__mtcc_t *mtcc; + mtcc_t *mtcc; + svn_editor3_t *editor; + const char *repos_root_url; apr_pool_t *iterpool = svn_pool_create(pool); - svn_error_t *err; int i; + svn_error_t *err; - SVN_ERR(svn_client__mtcc_create(&mtcc, anchor, - SVN_IS_VALID_REVNUM(base_revision) - ? base_revision - : SVN_INVALID_REVNUM, - ctx, pool, iterpool)); + /* Put the log message in the list of revprops, and check that the user + did not try to supply any other "svn:*" revprops. */ + if (svn_prop_has_svn_prop(revprops, pool)) + return svn_error_create(SVN_ERR_CLIENT_PROPERTY_NAME, NULL, + _("Standard properties can't be set " + "explicitly as revision properties")); + svn_hash_sets(revprops, SVN_PROP_REVISION_LOG, + svn_string_create(log_msg, pool)); + + SVN_ERR(mtcc_create(&mtcc, + anchor_url, base_revision, revprops, + commit_callback, NULL, + ctx, pool, iterpool)); + editor = mtcc->editor; + repos_root_url = mtcc->repos_root_url; + base_revision = mtcc->base_revision; for (i = 0; i < actions->nelts; ++i) { struct action *action = APR_ARRAY_IDX(actions, i, struct action *); - const char *path1, *path2; - svn_node_kind_t kind; + svn_editor3_peg_path_t path1_loc = {0}; + svn_editor3_txn_path_t path1_txn_loc = {{0},0}; + svn_editor3_txn_path_t path1_parent = {{0},0}; + const char *path1_name = NULL; + svn_editor3_txn_path_t path2_parent = {{0},0}; + const char *path2_name = NULL; svn_pool_clear(iterpool); + if (action->path[0]) + { + const char *rrpath1 + = svn_uri_skip_ancestor(repos_root_url, action->path[0], pool); + path1_loc = pathrev(rrpath1, base_revision); + path1_txn_loc = txn_path(rrpath1, base_revision, ""); /* ### need to + find which part of given path was pre-existing and which was created */ + path1_parent = txn_path(svn_relpath_dirname(rrpath1, pool), base_revision, ""); /* ### need to + find which part of given path was pre-existing and which was created */ + path1_name = svn_relpath_basename(rrpath1, NULL); + } + if (action->path[1] + && action->action != ACTION_PUT /* for which path2 is a local path */) + { + const char *rrpath2 + = svn_uri_skip_ancestor(repos_root_url, action->path[1], pool); + path2_parent = txn_path(svn_relpath_dirname(rrpath2, pool), base_revision, ""); /* ### need to + find which part of given path was pre-existing and which was created */ + path2_name = svn_relpath_basename(rrpath2, NULL); + } switch (action->action) { case ACTION_MV: - path1 = subtract_anchor(anchor, action->path[0], pool); - path2 = subtract_anchor(anchor, action->path[1], pool); - SVN_ERR(svn_client__mtcc_add_move(path1, path2, mtcc, iterpool)); + SVN_ERR(svn_editor3_mv(editor, path1_loc, path2_parent, path2_name)); break; case ACTION_CP: - path1 = subtract_anchor(anchor, action->path[0], pool); - path2 = subtract_anchor(anchor, action->path[1], pool); - SVN_ERR(svn_client__mtcc_add_copy(path1, action->rev, path2, - mtcc, iterpool)); + path1_loc.rev = action->rev; + SVN_ERR(svn_editor3_cp(editor, path1_loc, path2_parent, path2_name)); break; case ACTION_RM: - path1 = subtract_anchor(anchor, action->path[0], pool); - SVN_ERR(svn_client__mtcc_add_delete(path1, mtcc, iterpool)); + SVN_ERR(svn_editor3_rm(editor, path1_txn_loc)); break; case ACTION_MKDIR: - path1 = subtract_anchor(anchor, action->path[0], pool); - SVN_ERR(svn_client__mtcc_add_mkdir(path1, mtcc, iterpool)); + SVN_ERR(svn_editor3_mk(editor, svn_node_dir, path1_parent, path1_name)); break; case ACTION_PUT: - path1 = subtract_anchor(anchor, action->path[0], pool); - SVN_ERR(svn_client__mtcc_check_path(&kind, path1, TRUE, mtcc, pool)); - - if (kind == svn_node_dir) - { - SVN_ERR(svn_client__mtcc_add_delete(path1, mtcc, pool)); - kind = svn_node_none; - } - + /* Unlike svnmucc, here we always (try to) create a new file node, + without overwriting anything. */ { svn_stream_t *src; + svn_editor3_node_content_t *new_content; if (strcmp(action->path[1], "-") != 0) SVN_ERR(svn_stream_open_readonly(&src, action->path[1], @@ -195,48 +331,21 @@ execute(const apr_array_header_t *action else SVN_ERR(svn_stream_for_stdin(&src, pool)); - - if (kind == svn_node_file) - SVN_ERR(svn_client__mtcc_add_update_file(path1, src, NULL, - NULL, NULL, - mtcc, iterpool)); - else if (kind == svn_node_none) - SVN_ERR(svn_client__mtcc_add_add_file(path1, src, NULL, - mtcc, iterpool)); + new_content = svn_editor3_node_content_create_file( + path1_loc, NULL, NULL/*checksum*/, src, iterpool); + SVN_ERR(svn_editor3_mk(editor, svn_node_file, path1_parent, path1_name)); + SVN_ERR(svn_editor3_put(editor, path1_txn_loc, new_content)); } break; - case ACTION_PROPSET: - case ACTION_PROPDEL: - path1 = subtract_anchor(anchor, action->path[0], pool); - SVN_ERR(svn_client__mtcc_add_propset(path1, action->prop_name, - action->prop_value, FALSE, - mtcc, iterpool)); - break; - case ACTION_PROPSETF: default: - SVN_ERR_MALFUNCTION_NO_RETURN(); + SVN_ERR_MALFUNCTION(); } } - err = svn_client__mtcc_commit(revprops, commit_callback, NULL, - mtcc, iterpool); + err = mtcc_commit(mtcc, pool); svn_pool_destroy(iterpool); - return svn_error_trace(err);; -} - -static svn_error_t * -read_propvalue_file(const svn_string_t **value_p, - const char *filename, - apr_pool_t *pool) -{ - svn_stringbuf_t *value; - apr_pool_t *scratch_pool = svn_pool_create(pool); - - SVN_ERR(svn_stringbuf_from_file2(&value, filename, scratch_pool)); - *value_p = svn_string_create_from_buf(value, pool); - svn_pool_destroy(scratch_pool); - return SVN_NO_ERROR; + return svn_error_trace(err); } /* Perform the typical suite of manipulations for user-provided URLs @@ -256,9 +365,9 @@ static void usage(FILE *stream, apr_pool_t *pool) { svn_error_clear(svn_cmdline_fputs( - _("usage: svnmucc ACTION...\n" - "Subversion multiple URL command client.\n" - "Type 'svnmucc --version' to see the program version.\n" + _("usage: svnmover ACTION...\n" + "Subversion mover command client.\n" + "Type 'svnmover --version' to see the program version.\n" "\n" " Perform one or more Subversion repository URL-based ACTIONs, committing\n" " the result as a (single) new revision.\n" @@ -270,9 +379,6 @@ usage(FILE *stream, apr_pool_t *pool) " rm URL : delete URL\n" " put SRC-FILE URL : add or modify file URL with contents copied from\n" " SRC-FILE (use \"-\" to read from standard input)\n" - " propset NAME VALUE URL : set property NAME on URL to VALUE\n" - " propsetf NAME FILE URL : set property NAME on URL to value read from FILE\n" - " propdel NAME URL : delete property NAME from URL\n" "\n" "Valid options:\n" " -h, -? [--help] : display this text\n" @@ -317,7 +423,7 @@ display_version(apr_getopt_t *os, apr_po version_footer = svn_stringbuf_create(ra_desc_start, pool); SVN_ERR(svn_ra_print_modules(version_footer, pool)); - SVN_ERR(svn_opt_print_help4(os, "svnmucc", TRUE, FALSE, FALSE, + SVN_ERR(svn_opt_print_help4(os, "svnmover", TRUE, FALSE, FALSE, version_footer->data, NULL, NULL, NULL, NULL, NULL, pool)); @@ -377,29 +483,16 @@ sanitize_log_sources(const char **final_ return SVN_NO_ERROR; } -/* Baton for log_message_func */ -struct log_message_baton -{ - svn_boolean_t non_interactive; - const char *log_message; - svn_client_ctx_t *ctx; -}; - -/* Implements svn_client_get_commit_log3_t */ static svn_error_t * log_message_func(const char **log_msg, - const char **tmp_file, - const apr_array_header_t *commit_items, - void *baton, + svn_boolean_t non_interactive, + const char *log_message, + svn_client_ctx_t *ctx, apr_pool_t *pool) { - struct log_message_baton *lmb = baton; - - *tmp_file = NULL; - - if (lmb->log_message) + if (log_message) { - svn_string_t *message = svn_string_create(lmb->log_message, pool); + svn_string_t *message = svn_string_create(log_message, pool); SVN_ERR_W(svn_subst_translate_string2(&message, NULL, NULL, message, NULL, FALSE, @@ -411,7 +504,7 @@ log_message_func(const char **log_msg, return SVN_NO_ERROR; } - if (lmb->non_interactive) + if (non_interactive) { return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, NULL, _("Cannot invoke editor to get log message " @@ -422,8 +515,8 @@ log_message_func(const char **log_msg, svn_string_t *msg = svn_string_create("", pool); SVN_ERR(svn_cmdline__edit_string_externally( - &msg, NULL, NULL, "", msg, "svnmucc-commit", - lmb->ctx->config, TRUE, NULL, pool)); + &msg, NULL, NULL, "", msg, "svnmover-commit", + ctx->config, TRUE, NULL, pool)); if (msg && msg->data) *log_msg = msg->data; @@ -477,7 +570,7 @@ sub_main(int *exit_code, int argc, const {"version", version_opt, 0, ""}, {NULL, 0, 0, NULL} }; - const char *message = NULL; + const char *message = ""; svn_stringbuf_t *filedata = NULL; const char *username = NULL, *password = NULL; const char *root_url = NULL, *extra_args_file = NULL; @@ -493,7 +586,7 @@ sub_main(int *exit_code, int argc, const apr_hash_t *cfg_hash; svn_config_t *cfg_config; svn_client_ctx_t *ctx; - struct log_message_baton lmb; + const char *log_msg; int i; /* Check library versions */ @@ -644,7 +737,7 @@ sub_main(int *exit_code, int argc, const if (APR_STATUS_IS_EACCES(err->apr_err) || SVN__APR_STATUS_IS_ENOTDIR(err->apr_err)) { - svn_handle_warning2(stderr, err, "svnmucc: "); + svn_handle_warning2(stderr, err, "svnmover: "); svn_error_clear(err); SVN_ERR(svn_config__get_default_config(&cfg_hash, pool)); @@ -657,7 +750,7 @@ sub_main(int *exit_code, int argc, const { svn_error_clear( svn_cmdline__apply_config_options(cfg_hash, config_options, - "svnmucc: ", "--config-option")); + "svnmover: ", "--config-option")); } SVN_ERR(svn_client_create_context2(&ctx, cfg_hash, pool)); @@ -675,14 +768,14 @@ sub_main(int *exit_code, int argc, const ctx->cancel_baton, pool)); - lmb.non_interactive = non_interactive; - lmb.ctx = ctx; - /* Make sure we have a log message to use. */ - SVN_ERR(sanitize_log_sources(&lmb.log_message, message, revprops, filedata, + /* Make sure we have a log message to use. */ + SVN_ERR(sanitize_log_sources(&log_msg, message, revprops, filedata, pool, pool)); - ctx->log_msg_func3 = log_message_func; - ctx->log_msg_baton3 = &lmb; + /* Get the commit log message */ + SVN_ERR(log_message_func(&log_msg, non_interactive, log_msg, ctx, pool)); + if (! log_msg) + return SVN_NO_ERROR; /* Now, we iterate over the combined set of arguments -- our actions. */ for (i = 0; i < action_args->nelts; ) @@ -702,12 +795,6 @@ sub_main(int *exit_code, int argc, const action->action = ACTION_RM; else if (! strcmp(action_string, "put")) action->action = ACTION_PUT; - else if (! strcmp(action_string, "propset")) - action->action = ACTION_PROPSET; - else if (! strcmp(action_string, "propsetf")) - action->action = ACTION_PROPSETF; - else if (! strcmp(action_string, "propdel")) - action->action = ACTION_PROPDEL; else if (! strcmp(action_string, "?") || ! strcmp(action_string, "h") || ! strcmp(action_string, "help")) { @@ -760,62 +847,10 @@ sub_main(int *exit_code, int argc, const return insufficient(); } - /* For propset, propsetf, and propdel, a property name (and - maybe a property value or file which contains one) comes next. */ - if ((action->action == ACTION_PROPSET) - || (action->action == ACTION_PROPSETF) - || (action->action == ACTION_PROPDEL)) - { - action->prop_name = APR_ARRAY_IDX(action_args, i, const char *); - if (++i == action_args->nelts) - return insufficient(); - - if (action->action == ACTION_PROPDEL) - { - action->prop_value = NULL; - } - else if (action->action == ACTION_PROPSET) - { - action->prop_value = - svn_string_create(APR_ARRAY_IDX(action_args, i, - const char *), pool); - if (++i == action_args->nelts) - return insufficient(); - } - else - { - const char *propval_file = - svn_dirent_internal_style(APR_ARRAY_IDX(action_args, i, - const char *), pool); - - if (++i == action_args->nelts) - return insufficient(); - - SVN_ERR(read_propvalue_file(&(action->prop_value), - propval_file, pool)); - - action->action = ACTION_PROPSET; - } - - if (action->prop_value - && svn_prop_needs_translation(action->prop_name)) - { - svn_string_t *translated_value; - SVN_ERR_W(svn_subst_translate_string2(&translated_value, NULL, - NULL, action->prop_value, - NULL, FALSE, pool, pool), - "Error normalizing property value"); - action->prop_value = translated_value; - } - } - /* How many URLs does this action expect? */ if (action->action == ACTION_RM || action->action == ACTION_MKDIR - || action->action == ACTION_PUT - || action->action == ACTION_PROPSET - || action->action == ACTION_PROPSETF /* shouldn't see this one */ - || action->action == ACTION_PROPDEL) + || action->action == ACTION_PUT) num_url_args = 1; else num_url_args = 2; @@ -844,12 +879,9 @@ sub_main(int *exit_code, int argc, const url = sanitize_url(url, pool); action->path[j] = url; - /* The first URL arguments to 'cp', 'pd', 'ps' could be the anchor, + /* The first URL argument to 'cp' could be the anchor, but the other URLs should be children of the anchor. */ - if (! (action->action == ACTION_CP && j == 0) - && action->action != ACTION_PROPDEL - && action->action != ACTION_PROPSET - && action->action != ACTION_PROPSETF) + if (! (action->action == ACTION_CP && j == 0)) url = svn_uri_dirname(url, pool); if (! anchor) anchor = url; @@ -876,7 +908,7 @@ sub_main(int *exit_code, int argc, const return SVN_NO_ERROR; } - if ((err = execute(actions, anchor, revprops, base_revision, ctx, pool))) + if ((err = execute(actions, anchor, log_msg, revprops, base_revision, ctx, pool))) { if (err->apr_err == SVN_ERR_AUTHN_FAILED && non_interactive) err = svn_error_quick_wrap(err, @@ -897,7 +929,7 @@ main(int argc, const char *argv[]) svn_error_t *err; /* Initialize the app. */ - if (svn_cmdline_init("svnmucc", stderr) != EXIT_SUCCESS) + if (svn_cmdline_init("svnmover", stderr) != EXIT_SUCCESS) return EXIT_FAILURE; /* Create our top-level pool. Use a separate mutexless allocator, @@ -914,7 +946,7 @@ main(int argc, const char *argv[]) if (err) { exit_code = EXIT_FAILURE; - svn_cmdline_handle_exit_error(err, NULL, "svnmucc: "); + svn_cmdline_handle_exit_error(err, NULL, "svnmover: "); } svn_pool_destroy(pool);