Author: ivan
Date: Wed Apr 2 11:45:06 2014
New Revision: 1583977
URL: http://svn.apache.org/r1583977
Log:
Do not leave dead transaction if commit is blocked by start-commit hook. Also
fix svn_repos_fs_begin_txn_for_commit2() API promise regression that was
broken in r1376201.
* subversion/libsvn_repos/fs-wrap.c
(svn_repos_fs_begin_txn_for_commit2): Abort created transaction if error
happens between transaction creation and successful return from
function as promised in docstring. Also keep output *TXN_P
parameter unaffected on failure as promised in docstring.
* subversion/tests/cmdline/commit_tests.py
(start_commit_hook_test): Verify that there is no dead transaction left
when commit was blocked by start-commit hook.
Modified:
subversion/trunk/subversion/libsvn_repos/fs-wrap.c
subversion/trunk/subversion/tests/cmdline/commit_tests.py
Modified: subversion/trunk/subversion/libsvn_repos/fs-wrap.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/fs-wrap.c?rev=1583977&r1=1583976&r2=1583977&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/fs-wrap.c (original)
+++ subversion/trunk/subversion/libsvn_repos/fs-wrap.c Wed Apr 2 11:45:06 2014
@@ -136,6 +136,8 @@ svn_repos_fs_begin_txn_for_commit2(svn_f
const char *txn_name;
svn_string_t *author = svn_hash_gets(revprop_table,
SVN_PROP_REVISION_AUTHOR);
apr_hash_t *hooks_env;
+ svn_error_t *err;
+ svn_fs_txn_t *txn;
/* Parse the hooks-env file (if any). */
SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path,
@@ -143,21 +145,30 @@ svn_repos_fs_begin_txn_for_commit2(svn_f
/* Begin the transaction, ask for the fs to do on-the-fly lock checks.
We fetch its name, too, so the start-commit hook can use it. */
- SVN_ERR(svn_fs_begin_txn2(txn_p, repos->fs, rev,
+ SVN_ERR(svn_fs_begin_txn2(&txn, repos->fs, rev,
SVN_FS_TXN_CHECK_LOCKS, pool));
- SVN_ERR(svn_fs_txn_name(&txn_name, *txn_p, pool));
+ err = svn_fs_txn_name(&txn_name, txn, pool);
+ if (err)
+ return svn_error_compose_create(err, svn_fs_abort_txn(txn, pool));
/* We pass the revision properties to the filesystem by adding them
as properties on the txn. Later, when we commit the txn, these
properties will be copied into the newly created revision. */
revprops = svn_prop_hash_to_array(revprop_table, pool);
- SVN_ERR(svn_repos_fs_change_txn_props(*txn_p, revprops, pool));
+ err = svn_repos_fs_change_txn_props(txn, revprops, pool);
+ if (err)
+ return svn_error_compose_create(err, svn_fs_abort_txn(txn, pool));
/* Run start-commit hooks. */
- SVN_ERR(svn_repos__hooks_start_commit(repos, hooks_env,
- author ? author->data : NULL,
- repos->client_capabilities, txn_name,
- pool));
+ err = svn_repos__hooks_start_commit(repos, hooks_env,
+ author ? author->data : NULL,
+ repos->client_capabilities, txn_name,
+ pool);
+ if (err)
+ return svn_error_compose_create(err, svn_fs_abort_txn(txn, pool));
+
+ /* We have API promise that *TXN_P is unaffected on faulure. */
+ *txn_p = txn;
return SVN_NO_ERROR;
}
Modified: subversion/trunk/subversion/tests/cmdline/commit_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/commit_tests.py?rev=1583977&r1=1583976&r2=1583977&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/commit_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/commit_tests.py Wed Apr 2
11:45:06 2014
@@ -2545,6 +2545,16 @@ def start_commit_hook_test(sbox):
'STDERR',
expected_stderr, actual_stderr)
+ # Now list the txns in the repo. The list should be empty.
+ exit_code, output, errput = svntest.main.run_svnadmin('lstxns',
+ sbox.repo_dir)
+ svntest.verify.compare_and_display_lines(
+ "Error running 'svnadmin lstxns'.",
+ 'STDERR', [], errput)
+ svntest.verify.compare_and_display_lines(
+ "Output of 'svnadmin lstxns' is unexpected.",
+ 'STDOUT', [], output)
+
#----------------------------------------------------------------------
@Issue(3553)
def pre_commit_hook_test(sbox):