=== subversion/libsvn_ra/ra_loader.c ================================================================== --- subversion/libsvn_ra/ra_loader.c (revision 21048) +++ subversion/libsvn_ra/ra_loader.c (patch set-revprop-for-commit level 8) @@ -418,6 +418,15 @@ keep_locks, pool); } +svn_error_t *svn_ra_set_revprop_for_commit(svn_ra_session_t *session, + const char *name, + const svn_string_t *val, + apr_pool_t *pool) +{ + return session->vtable->set_revprop_for_commit(session, name, val, pool); +} + + svn_error_t *svn_ra_get_file(svn_ra_session_t *session, const char *path, svn_revnum_t revision, === subversion/libsvn_ra/ra_loader.h ================================================================== --- subversion/libsvn_ra/ra_loader.h (revision 21048) +++ subversion/libsvn_ra/ra_loader.h (patch set-revprop-for-commit level 8) @@ -211,6 +211,10 @@ const svn_delta_editor_t *editor, void *edit_baton, apr_pool_t *pool); + svn_error_t *(*set_revprop_for_commit)(svn_ra_session_t *session, + const char *name, + const svn_string_t *val, + apr_pool_t *pool); } svn_ra__vtable_t; /* The RA session object. */ === subversion/include/svn_error_codes.h ================================================================== --- subversion/include/svn_error_codes.h (revision 21048) +++ subversion/include/svn_error_codes.h (patch set-revprop-for-commit level 8) @@ -759,6 +759,10 @@ SVN_ERRDEF(SVN_ERR_RA_SVN_BAD_VERSION, SVN_ERR_RA_SVN_CATEGORY_START + 6, "Client/server version mismatch") + + SVN_ERRDEF(SVN_ERR_RA_SVN_INVALID_SET_REVPROP, + SVN_ERR_RA_SVN_CATEGORY_START + 7, + "No transaction to set properties on") /* libsvn_auth errors */ === subversion/include/svn_repos.h ================================================================== --- subversion/include/svn_repos.h (revision 21048) +++ subversion/include/svn_repos.h (patch set-revprop-for-commit level 8) @@ -675,10 +675,15 @@ * * @a repos is a previously opened repository. @a repos_url is the * decoded URL to the base of the repository, and is used to check - * copyfrom paths. @a txn is a filesystem transaction object to use - * during the commit, or @c NULL to indicate that this function should - * create (and fully manage) a new transaction. + * copyfrom paths. * + * @a txn is a filesystem transaction object to use during the commit, + * or @c NULL to indicate that this function should create (and fully + * manage) a new transaction. In the latter case, if @a txn_out is not + * NULL, it returns the managed transaction to the caller; the + * transaction's lifetime is still managed by this function, and is + * mostly useful for setting transaction properties. + * * Iff @a user is not @c NULL, store it as the author of the commit * transaction. * @@ -704,7 +709,32 @@ * NULL). Callers who supply their own transactions are responsible * for cleaning them up (either by committing them, or aborting them). * + * @since New in 1.5. + */ + +svn_error_t * +svn_repos_get_commit_editor5(const svn_delta_editor_t **editor, + void **edit_baton, + svn_repos_t *repos, + svn_fs_txn_t *txn, + svn_fs_txn_t **txn_out, + const char *repos_url, + const char *base_path, + const char *user, + const char *log_msg, + svn_commit_callback2_t callback, + void *callback_baton, + svn_repos_authz_callback_t authz_callback, + void *authz_baton, + apr_pool_t *pool); + +/** + * Similar to svn_repos_get_commit_editor5(), but + * always passes in @c NULL for @a txn_out. + * * @since New in 1.4. + * + * @deprecated Provided for backward compatibility with the 1.4 API. */ svn_error_t * svn_repos_get_commit_editor4(const svn_delta_editor_t **editor, === subversion/include/svn_ra_svn.h ================================================================== --- subversion/include/svn_ra_svn.h (revision 21048) +++ subversion/include/svn_ra_svn.h (patch set-revprop-for-commit level 8) @@ -31,6 +31,7 @@ #include "svn_config.h" #include "svn_delta.h" +#include "svn_fs.h" #ifdef __cplusplus extern "C" { @@ -344,15 +345,30 @@ apr_pool_t *pool, svn_ra_svn_edit_callback callback, void *callback_baton); -/** Receive edit commands over the network and use them to drive @a editor - * with @a edit_baton. On return, @a *aborted will be set if the edit was - * aborted. +/** Receive edit commands over the network and use them to drive @a + * editor with @a edit_baton in the context of transaction txn. On + * return, @a *aborted will be set if the edit was aborted. + * + * @since New in 1.5. */ +svn_error_t *svn_ra_svn_drive_editor2(svn_ra_svn_conn_t *conn, apr_pool_t *pool, + const svn_delta_editor_t *editor, + void *edit_baton, + svn_fs_txn_t *txn, + svn_boolean_t *aborted); + +/** + * Same as svn_ra_svn_drive_editor2(), but with @a txn set to @c NULL. + * (This editor will not support svn_ra_set_revprop_for_commit.) + * + * @deprecated Provided for backward compatibility with the 1.4 API. + */ svn_error_t *svn_ra_svn_drive_editor(svn_ra_svn_conn_t *conn, apr_pool_t *pool, const svn_delta_editor_t *editor, void *edit_baton, svn_boolean_t *aborted); + /** This function is only intended for use by svnserve. * * Perform CRAM-MD5 password authentication. On success, return === subversion/include/svn_ra.h ================================================================== --- subversion/include/svn_ra.h (revision 21048) +++ subversion/include/svn_ra.h (patch set-revprop-for-commit level 8) @@ -584,8 +584,8 @@ * If @a keep_locks is @c TRUE, then do not release locks on * committed objects. Else, automatically release such locks. * - * The caller may not perform any RA operations using @a session before - * finishing the edit. + * The caller may not perform any RA operations using @a session + * except for svn_ra_set_revprop_for_commit before finishing the edit. * * Use @a pool for memory allocation. * @@ -619,6 +619,22 @@ apr_pool_t *pool); /** + * Set the unversioned revision property @a name to @a value on the + * revision currently being committed in @a session. + * + * This may only be called between a call to svn_ra_get_commit_editor2 + * and its corresponding close_edit. + * + * Use @a pool for memory allocation. + * + * @since New in 1.5. + */ +svn_error_t *svn_ra_set_revprop_for_commit(svn_ra_session_t *session, + const char *name, + const svn_string_t *val, + apr_pool_t *pool); + +/** * Fetch the contents and properties of file @a path at @a revision. * Interpret @a path relative to the URL in @a session. Use * @a pool for all allocations. === subversion/libsvn_ra_local/ra_plugin.c ================================================================== --- subversion/libsvn_ra_local/ra_plugin.c (revision 21048) +++ subversion/libsvn_ra_local/ra_plugin.c (patch set-revprop-for-commit level 8) @@ -536,8 +536,9 @@ } /* Get the repos commit-editor */ - SVN_ERR(svn_repos_get_commit_editor4 + SVN_ERR(svn_repos_get_commit_editor5 (editor, edit_baton, sess_baton->repos, NULL, + &(sess_baton->txn), svn_path_uri_decode(sess_baton->repos_url, pool), sess_baton->fs_path->data, sess_baton->username, log_msg, @@ -546,7 +547,23 @@ return SVN_NO_ERROR; } +static svn_error_t * +svn_ra_local__set_revprop_for_commit(svn_ra_session_t *session, + const char *name, + const svn_string_t *val, + apr_pool_t *pool) +{ + svn_ra_local__session_baton_t *sess_baton = session->priv; + svn_fs_txn_t *txn = sess_baton->txn; + SVN_ERR(svn_fs_change_txn_prop(txn, + name, + val, + pool)); + + return SVN_NO_ERROR; +} + static svn_error_t * make_reporter(svn_ra_session_t *session, const svn_ra_reporter2_t **reporter, @@ -1313,6 +1330,7 @@ svn_ra_local__get_lock, svn_ra_local__get_locks, svn_ra_local__replay, + svn_ra_local__set_revprop_for_commit, }; === subversion/libsvn_ra_local/ra_local.h ================================================================== --- subversion/libsvn_ra_local/ra_local.h (revision 21048) +++ subversion/libsvn_ra_local/ra_local.h (patch set-revprop-for-commit level 8) @@ -54,6 +54,9 @@ /* The UUID associated with REPOS above (cached) */ const char *uuid; + /* The transaction for the currently open commit editor, if any. */ + svn_fs_txn_t *txn; + /* Callbacks/baton passed to svn_ra_open. */ const svn_ra_callbacks2_t *callbacks; void *callback_baton; === subversion/tests/libsvn_ra_local/ra-local-test.c ================================================================== --- subversion/tests/libsvn_ra_local/ra-local-test.c (revision 21048) +++ subversion/tests/libsvn_ra_local/ra-local-test.c (patch set-revprop-for-commit level 8) @@ -156,7 +156,88 @@ return SVN_NO_ERROR; } +static svn_error_t * +commit_callback(const svn_commit_info_t *commit_info, + void *baton, + apr_pool_t *pool) +{ + return SVN_NO_ERROR; +} +/* Set some revprops atomically */ +static svn_error_t * +set_revprops_atomically(const char **msg, + svn_boolean_t msg_only, + svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_ra_session_t *session; + const svn_delta_editor_t *editor; + void *edit_baton, *root_baton, *dir_baton; + svn_revnum_t latest_rev; + svn_string_t *value, *bar_string; + + *msg = "set revprops atomically"; + + if (msg_only) + return SVN_NO_ERROR; + + SVN_ERR(make_and_open_local_repos(&session, + "test-repo-revprop-atomically", opts->fs_type, + pool)); + + SVN_ERR(svn_ra_get_commit_editor2(session, + &editor, + &edit_baton, + "log", + commit_callback, + NULL, + NULL, + FALSE, + pool)); + + /* Do some random things to make this a non-trivial commit */ + SVN_ERR(editor->open_root(edit_baton, + 0, + pool, + &root_baton)); + SVN_ERR(editor->add_directory("blah", + root_baton, + NULL, 0, + pool, + &dir_baton)); + SVN_ERR(editor->close_directory(dir_baton, pool)); + + bar_string = svn_string_create("bar", pool); + + SVN_ERR(svn_ra_set_revprop_for_commit(session, + "foo", + bar_string, + pool)); + + SVN_ERR(editor->close_edit(edit_baton, pool)); + + /* Get the youngest revision and make sure it's 1. */ + SVN_ERR(svn_ra_get_latest_revnum(session, &latest_rev, pool)); + + if (latest_rev != 1) + return svn_error_create(SVN_ERR_FS_GENERAL, NULL, + "youngest rev isn't 1!"); + + SVN_ERR(svn_ra_rev_prop(session, + latest_rev, + "foo", + &value, + pool)); + + if (value == NULL || !svn_string_compare(value, bar_string)) + return svn_error_create(SVN_ERR_FS_GENERAL, NULL, + "revprop value not set!"); + + return SVN_NO_ERROR; +} + + /* Helper function. Run svn_ra_local__split_URL with interest only in the return error code */ static apr_status_t @@ -348,6 +429,7 @@ SVN_TEST_NULL, SVN_TEST_PASS(open_ra_session), SVN_TEST_PASS(get_youngest_rev), + SVN_TEST_PASS(set_revprops_atomically), SVN_TEST_PASS(split_url_syntax), SVN_TEST_SKIP(split_url_bad_host, HAS_UNC_HOST), SVN_TEST_PASS(split_url_host), === subversion/svnsync/main.c ================================================================== --- subversion/svnsync/main.c (revision 21048) +++ subversion/svnsync/main.c (patch set-revprop-for-commit level 8) @@ -372,7 +372,47 @@ return SVN_NO_ERROR; } +/* Like copy_revprops, but in the context of a commit, so we can make + * the revprop changes atomically. + */ +static svn_error_t * +copy_revprops_atomically(svn_ra_session_t *from_session, + svn_ra_session_t *to_session, + svn_revnum_t rev, + apr_pool_t *pool) +{ + apr_pool_t *subpool = svn_pool_create(pool); + apr_hash_t *revprops; + svn_boolean_t saw_sync_props = FALSE; + apr_hash_index_t *hi; + SVN_ERR(svn_ra_rev_proplist(from_session, rev, &revprops, pool)); + + for (hi = apr_hash_first(pool, revprops); hi; hi = apr_hash_next(hi)) + { + const void *key; + void *val; + + svn_pool_clear(subpool); + apr_hash_this(hi, &key, NULL, &val); + + if (strncmp(key, PROP_PREFIX, sizeof(PROP_PREFIX) - 1) == 0) + saw_sync_props = TRUE; + else + SVN_ERR(svn_ra_set_revprop_for_commit(to_session, key, val, subpool)); + } + + if (saw_sync_props) + SVN_ERR(svn_cmdline_printf(subpool, + _("Skipped %s* properties when copying revision %ld.\n"), + PROP_PREFIX, rev)); + + svn_pool_destroy(subpool); + + return SVN_NO_ERROR; +} + + /*** `svnsync init' ***/ @@ -1058,6 +1098,11 @@ commit_callback, baton, NULL, FALSE, subpool)); + /* Since we're actually making a commit, we can copy the + * revprops as part of the transaction. */ + SVN_ERR(copy_revprops_atomically(from_session, to_session, current, subpool)); + + /* There's one catch though, the diff shows us props we can't send over the RA interface, so we need an editor that's smart enough to filter those out for us. */ @@ -1082,11 +1127,6 @@ _("Commit created rev %ld but should have created %ld"), baton->committed_rev, current); - /* Ok, we're done with the data, now we just need to do the - revprops and we're all set. */ - - SVN_ERR(copy_revprops(from_session, to_session, current, subpool)); - /* Ok, we're done, bring the last-merged-rev property up to date. */ SVN_ERR(svn_ra_change_rev_prop === subversion/libsvn_repos/commit.c ================================================================== --- subversion/libsvn_repos/commit.c (revision 21048) +++ subversion/libsvn_repos/commit.c (patch set-revprop-for-commit level 8) @@ -168,46 +168,7 @@ { struct dir_baton *dirb; struct edit_baton *eb = edit_baton; - svn_revnum_t youngest; - /* Ignore BASE_REVISION. We always build our transaction against - HEAD. However, we will keep it in our dir baton for out of - dateness checks. */ - SVN_ERR(svn_fs_youngest_rev(&youngest, eb->fs, eb->pool)); - - /* Unless we've been instructed to use a specific transaction, we'll - make our own. */ - if (eb->txn_owner) - { - SVN_ERR(svn_repos_fs_begin_txn_for_commit(&(eb->txn), - eb->repos, - youngest, - eb->user, - eb->log_msg, - eb->pool)); - } - else /* Even if we aren't the owner of the transaction, we might - have been instructed to set some properties. */ - { - svn_string_t propval; - if (eb->user) - { - propval.data = eb->user; - propval.len = strlen(eb->user); - SVN_ERR(svn_fs_change_txn_prop(eb->txn, SVN_PROP_REVISION_AUTHOR, - &propval, pool)); - } - if (eb->log_msg) - { - propval.data = eb->log_msg; - propval.len = strlen(eb->log_msg); - SVN_ERR(svn_fs_change_txn_prop(eb->txn, SVN_PROP_REVISION_LOG, - &propval, pool)); - } - } - SVN_ERR(svn_fs_txn_name(&(eb->txn_name), eb->txn, eb->pool)); - SVN_ERR(svn_fs_txn_root(&(eb->txn_root), eb->txn, eb->pool)); - /* Create a root dir baton. The `base_path' field is an -absolute- path in the filesystem, upon which all further editor paths are based. */ @@ -764,10 +725,11 @@ /*** Public interfaces. ***/ svn_error_t * -svn_repos_get_commit_editor4(const svn_delta_editor_t **editor, +svn_repos_get_commit_editor5(const svn_delta_editor_t **editor, void **edit_baton, svn_repos_t *repos, svn_fs_txn_t *txn, + svn_fs_txn_t **txn_out, const char *repos_url, const char *base_path, const char *user, @@ -781,6 +743,7 @@ svn_delta_editor_t *e; apr_pool_t *subpool = svn_pool_create(pool); struct edit_baton *eb; + svn_revnum_t youngest; /* Do a global authz access lookup. Users with no write access whatsoever to the repository don't get a commit editor. */ @@ -830,6 +793,46 @@ eb->txn = txn; eb->txn_owner = txn ? FALSE : TRUE; + /* Ignore BASE_REVISION. We always build our transaction against + HEAD. However, we will keep it in our dir baton for out of + dateness checks. */ + SVN_ERR(svn_fs_youngest_rev(&youngest, eb->fs, subpool)); + + /* Unless we've been instructed to use a specific transaction, we'll + make our own. */ + if (eb->txn_owner) + { + SVN_ERR(svn_repos_fs_begin_txn_for_commit(&(eb->txn), + eb->repos, + youngest, + eb->user, + eb->log_msg, + eb->pool)); + if (txn_out) + *txn_out = eb->txn; + } + else /* Even if we aren't the owner of the transaction, we might + have been instructed to set some properties. */ + { + svn_string_t propval; + if (eb->user) + { + propval.data = eb->user; + propval.len = strlen(eb->user); + SVN_ERR(svn_fs_change_txn_prop(eb->txn, SVN_PROP_REVISION_AUTHOR, + &propval, pool)); + } + if (eb->log_msg) + { + propval.data = eb->log_msg; + propval.len = strlen(eb->log_msg); + SVN_ERR(svn_fs_change_txn_prop(eb->txn, SVN_PROP_REVISION_LOG, + &propval, pool)); + } + } + SVN_ERR(svn_fs_txn_name(&(eb->txn_name), eb->txn, eb->pool)); + SVN_ERR(svn_fs_txn_root(&(eb->txn_root), eb->txn, eb->pool)); + *edit_baton = eb; *editor = e; @@ -837,6 +840,37 @@ } svn_error_t * +svn_repos_get_commit_editor4(const svn_delta_editor_t **editor, + void **edit_baton, + svn_repos_t *repos, + svn_fs_txn_t *txn, + const char *repos_url, + const char *base_path, + const char *user, + const char *log_msg, + svn_commit_callback2_t callback, + void *callback_baton, + svn_repos_authz_callback_t authz_callback, + void *authz_baton, + apr_pool_t *pool) +{ + return svn_repos_get_commit_editor5(editor, + edit_baton, + repos, + txn, + NULL, + repos_url, + base_path, + user, + log_msg, + callback, + callback_baton, + authz_callback, + authz_baton, + pool); +} + +svn_error_t * svn_repos_get_commit_editor3(const svn_delta_editor_t **editor, void **edit_baton, svn_repos_t *repos, === subversion/libsvn_ra_svn/client.c ================================================================== --- subversion/libsvn_ra_svn/client.c (revision 21048) +++ subversion/libsvn_ra_svn/client.c (patch set-revprop-for-commit level 8) @@ -838,6 +838,20 @@ return SVN_NO_ERROR; } +static svn_error_t *ra_svn_set_revprop_for_commit(svn_ra_session_t *session, + const char *name, + const svn_string_t *value, + apr_pool_t *pool) +{ + svn_ra_svn__session_baton_t *sess_baton = session->priv; + svn_ra_svn_conn_t *conn = sess_baton->conn; + + SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "set-rev-prop", "cs", + name, value)); + return SVN_NO_ERROR; +} + + static svn_error_t *ra_svn_get_file(svn_ra_session_t *session, const char *path, svn_revnum_t rev, svn_stream_t *stream, svn_revnum_t *fetched_rev, @@ -1901,6 +1915,7 @@ ra_svn_get_lock, ra_svn_get_locks, ra_svn_replay, + ra_svn_set_revprop_for_commit, }; svn_error_t * === subversion/libsvn_ra_svn/protocol ================================================================== --- subversion/libsvn_ra_svn/protocol (revision 21048) +++ subversion/libsvn_ra_svn/protocol (patch set-revprop-for-commit level 8) @@ -461,6 +461,11 @@ params: ( ) response: ( ) + set-rev-prop + params: ( name:string value:string ) + (For svn_ra_set_revprop_for_commit.) + + 3.1.3. Report Command Set To reduce round-trip delays, report commands do not return responses. === subversion/libsvn_ra_svn/editor.c ================================================================== --- subversion/libsvn_ra_svn/editor.c (revision 21048) +++ subversion/libsvn_ra_svn/editor.c (patch set-revprop-for-commit level 8) @@ -722,15 +722,16 @@ { NULL } }; -svn_error_t *svn_ra_svn_drive_editor(svn_ra_svn_conn_t *conn, apr_pool_t *pool, - const svn_delta_editor_t *editor, - void *edit_baton, - svn_boolean_t *aborted) +svn_error_t *svn_ra_svn_drive_editor2(svn_ra_svn_conn_t *conn, apr_pool_t *pool, + const svn_delta_editor_t *editor, + void *edit_baton, + svn_fs_txn_t *txn, + svn_boolean_t *aborted) { ra_svn_driver_state_t state; if (svn_ra_svn_has_capability(conn, SVN_RA_SVN_CAP_EDIT_PIPELINE)) - return svn_ra_svn__drive_editorp(conn, pool, editor, edit_baton, aborted); + return svn_ra_svn__drive_editorp(conn, pool, editor, edit_baton, txn, aborted); state.editor = editor; state.edit_baton = edit_baton; @@ -739,3 +740,11 @@ state.pool = pool; return svn_ra_svn_handle_commands(conn, pool, ra_svn_edit_commands, &state); } + +svn_error_t *svn_ra_svn_drive_editor(svn_ra_svn_conn_t *conn, apr_pool_t *pool, + const svn_delta_editor_t *editor, + void *edit_baton, + svn_boolean_t *aborted) +{ + return svn_ra_svn_drive_editor2(conn, pool, editor, edit_baton, NULL, aborted); +} === subversion/libsvn_ra_svn/editorp.c ================================================================== --- subversion/libsvn_ra_svn/editorp.c (revision 21048) +++ subversion/libsvn_ra_svn/editorp.c (patch set-revprop-for-commit level 8) @@ -31,6 +31,7 @@ #include "svn_error.h" #include "svn_path.h" #include "svn_delta.h" +#include "svn_fs.h" #include "svn_ra_svn.h" #include "svn_pools.h" #include "svn_private_config.h" @@ -71,6 +72,7 @@ apr_pool_t *pool; apr_pool_t *file_pool; int file_refs; + svn_fs_txn_t *txn; } ra_svn_driver_state_t; /* Works for both directories and files; however, the pool handling is @@ -788,6 +790,23 @@ return svn_ra_svn_write_cmd_response(conn, pool, ""); } +static svn_error_t *ra_svn_handle_set_revprop_for_commit(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + apr_array_header_t *params, + ra_svn_driver_state_t *ds) +{ + const char *name; + svn_string_t *val; + + SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "cs", &name, &val)); + if (! ds->txn) + return svn_error_create(SVN_ERR_RA_SVN_INVALID_SET_REVPROP, NULL, NULL); + + SVN_CMD_ERR(svn_fs_change_txn_prop(ds->txn, name, val, pool)); + + return SVN_NO_ERROR; +} + static const struct { const char *cmd; svn_error_t *(*handler)(svn_ra_svn_conn_t *conn, apr_pool_t *pool, @@ -812,6 +831,7 @@ { "absent-file", ra_svn_handle_absent_file }, { "close-edit", ra_svn_handle_close_edit }, { "abort-edit", ra_svn_handle_abort_edit }, + { "set-rev-prop", ra_svn_handle_set_revprop_for_commit }, { NULL } }; @@ -837,6 +857,7 @@ apr_pool_t *pool, const svn_delta_editor_t *editor, void *edit_baton, + svn_fs_txn_t *txn, svn_boolean_t *aborted) { ra_svn_driver_state_t state; @@ -854,6 +875,7 @@ state.pool = pool; state.file_pool = svn_pool_create(pool); state.file_refs = 0; + state.txn = txn; while (!state.done) { === subversion/libsvn_ra_svn/ra_svn.h ================================================================== --- subversion/libsvn_ra_svn/ra_svn.h (revision 21048) +++ subversion/libsvn_ra_svn/ra_svn.h (patch set-revprop-for-commit level 8) @@ -29,6 +29,7 @@ #include #include #include "svn_ra_svn.h" +#include "svn_fs.h" /* Handler for blocked writes. */ typedef svn_error_t *(*ra_svn_block_handler_t)(svn_ra_svn_conn_t *conn, @@ -92,6 +93,7 @@ apr_pool_t *pool, const svn_delta_editor_t *editor, void *edit_baton, + svn_fs_txn_t *txn, svn_boolean_t *aborted); /* CRAM-MD5 client implementation. */ === subversion/svnserve/serve.c ================================================================== --- subversion/svnserve/serve.c (revision 21048) +++ subversion/svnserve/serve.c (patch set-revprop-for-commit level 8) @@ -927,7 +927,9 @@ svn_boolean_t aborted; commit_callback_baton_t ccb; svn_revnum_t new_rev; + svn_fs_txn_t *txn; + if (params->nelts == 1) { /* Clients before 1.2 don't send lock-tokens and keep-locks fields. */ @@ -958,15 +960,16 @@ ccb.date = &date; ccb.author = &author; ccb.post_commit_err = &post_commit_err; + /* ### Note that svn_repos_get_commit_editor actually wants a decoded URL. */ - SVN_CMD_ERR(svn_repos_get_commit_editor4 - (&editor, &edit_baton, b->repos, NULL, + SVN_CMD_ERR(svn_repos_get_commit_editor5 + (&editor, &edit_baton, b->repos, NULL, &txn, svn_path_uri_decode(b->repos_url, pool), b->fs_path->data, b->user, log_msg, commit_done, &ccb, authz_commit_cb, baton, pool)); SVN_ERR(svn_ra_svn_write_cmd_response(conn, pool, "")); - SVN_ERR(svn_ra_svn_drive_editor(conn, pool, editor, edit_baton, &aborted)); + SVN_ERR(svn_ra_svn_drive_editor2(conn, pool, editor, edit_baton, txn, &aborted)); if (!aborted) { SVN_ERR(trivial_auth_request(conn, pool, b));