Index: subversion/include/svn_types.h
===================================================================
--- subversion/include/svn_types.h (revision 14664)
+++ subversion/include/svn_types.h (working copy)
@@ -349,6 +349,7 @@
svn_revnum_t new_revision,
const char *date,
const char *author,
+ const char *post_commit_err,
void *baton);
Index: subversion/include/svn_client.h
===================================================================
--- subversion/include/svn_client.h (revision 14664)
+++ subversion/include/svn_client.h (working copy)
@@ -275,6 +275,9 @@
/** author of the commit. */
const char *author;
+ /** post-commit hook's stderr. */
+ const char *post_commit_err;
+
} svn_client_commit_info_t;
Index: subversion/libsvn_ra_local/ra_plugin.c
===================================================================
--- subversion/libsvn_ra_local/ra_plugin.c (revision 14664)
+++ subversion/libsvn_ra_local/ra_plugin.c (working copy)
@@ -420,6 +420,7 @@
deltify_etc (svn_revnum_t new_revision,
const char *date,
const char *author,
+ const char *post_commit_err,
void *baton)
{
struct deltify_etc_baton *db = baton;
@@ -430,7 +431,8 @@
/* Invoke the original callback first, in case someone's waiting to
know the revision number so they can go off and annotate an
issue or something. */
- err1 = (*db->callback) (new_revision, date, author, db->callback_baton);
+ err1 = (*db->callback) (new_revision, date, author,
+ post_commit_err, db->callback_baton);
/* Maybe unlock the paths. */
if (db->lock_tokens)
Index: subversion/libsvn_client/client.h
===================================================================
--- subversion/libsvn_client/client.h (revision 14664)
+++ subversion/libsvn_client/client.h (working copy)
@@ -255,6 +255,7 @@
svn_error_t *svn_client__commit_callback (svn_revnum_t revision,
const char *date,
const char *author,
+ const char *post_commit_err,
void *baton);
/* ---------------------------------------------------------------- */
Index: subversion/libsvn_client/commit_util.c
===================================================================
--- subversion/libsvn_client/commit_util.c (revision 14664)
+++ subversion/libsvn_client/commit_util.c (working copy)
@@ -1324,6 +1324,7 @@
svn_error_t *svn_client__commit_callback (svn_revnum_t revision,
const char *date,
const char *author,
+ const char *post_commit_err,
void *baton)
{
struct commit_baton *cb = baton;
@@ -1333,6 +1334,7 @@
(*info)->date = date ? apr_pstrdup (cb->pool, date) : NULL;
(*info)->author = author ? apr_pstrdup (cb->pool, author) : NULL;
(*info)->revision = revision;
+ (*info)->post_commit_err = post_commit_err ? apr_pstrdup (cb->pool, post_commit_err) : NULL;
return SVN_NO_ERROR;
}
Index: subversion/mod_dav_svn/merge.c
===================================================================
--- subversion/mod_dav_svn/merge.c (revision 14664)
+++ subversion/mod_dav_svn/merge.c (working copy)
@@ -29,6 +29,7 @@
#include "svn_props.h"
#include "dav_svn.h"
+#include "svn_xml.h"
/* #################################################################
@@ -200,6 +201,7 @@
dav_error * dav_svn__merge_response(ap_filter_t *output,
const dav_svn_repos *repos,
svn_revnum_t new_rev,
+ char *post_commit_err,
apr_xml_elem *prop_elem,
svn_boolean_t disable_merge_response,
apr_pool_t *pool)
@@ -209,6 +211,7 @@
svn_error_t *serr;
const char *vcc;
const char *rev;
+ const char *post_commit_err_elem;
svn_string_t *creationdate, *creator_displayname;
serr = svn_fs_revision_root(&root, repos->fs, new_rev, pool);
@@ -231,6 +234,15 @@
/* the version-name of the baseline is the revision number */
rev = apr_psprintf(pool, "%ld", new_rev);
+ /* get the post-commit hook stderr, if any */
+ if (post_commit_err)
+ post_commit_err_elem = apr_psprintf(pool,
+ "%s"
+ "",
+ post_commit_err);
+ else
+ post_commit_err_elem = "" ;
+
/* get the creationdate and creator-displayname of the new revision, too. */
serr = svn_fs_revision_prop(&creationdate, repos->fs, new_rev,
SVN_PROP_REVISION_DATE, pool);
@@ -252,7 +264,8 @@
(void) ap_fputstrs(output, bb,
DAV_XML_HEADER DEBUG_CR
- "" DEBUG_CR
+ "" DEBUG_CR
"" DEBUG_CR
/* generate a response for the new baseline */
@@ -264,7 +277,8 @@
/* ### this is wrong. it's a VCC, not a baseline. but
### we need to tell the client to look at *this*
### resource for the version-name. */
- "" DEBUG_CR
+ "" DEBUG_CR,
+ post_commit_err_elem, DEBUG_CR
"", rev, "" DEBUG_CR,
NULL);
if (creationdate)
Index: subversion/mod_dav_svn/dav_svn.h
===================================================================
--- subversion/mod_dav_svn/dav_svn.h (revision 14664)
+++ subversion/mod_dav_svn/dav_svn.h (working copy)
@@ -500,6 +500,7 @@
dav_error * dav_svn__merge_response(ap_filter_t *output,
const dav_svn_repos *repos,
svn_revnum_t new_rev,
+ char *post_commit_err,
apr_xml_elem *prop_elem,
svn_boolean_t disable_merge_response,
apr_pool_t *pool);
Index: subversion/mod_dav_svn/version.c
===================================================================
--- subversion/mod_dav_svn/version.c (revision 14664)
+++ subversion/mod_dav_svn/version.c (working copy)
@@ -1619,6 +1619,7 @@
svn_fs_txn_t *txn;
const char *conflict;
svn_error_t *serr;
+ char *post_commit_err = NULL ;
svn_revnum_t new_rev;
apr_hash_t *locks;
svn_boolean_t disable_merge_response = FALSE;
@@ -1699,7 +1700,8 @@
return dav_svn_convert_err(serr, HTTP_CONFLICT, msg, pool);
}
else if (serr)
- svn_error_clear(serr);
+ if (serr->child->message)
+ post_commit_err = apr_pstrdup (pool, serr->child->message);
/* Commit was successful, so schedule deltification. */
register_deltification_cleanup(source->info->repos->repos, new_rev,
@@ -1740,7 +1742,8 @@
/* process the response for the new revision. */
return dav_svn__merge_response(output, source->info->repos, new_rev,
- prop_elem, disable_merge_response, pool);
+ post_commit_err, prop_elem,
+ disable_merge_response, pool);
}
const dav_hooks_vsn dav_svn_hooks_vsn = {
Index: subversion/clients/cmdline/util.c
===================================================================
--- subversion/clients/cmdline/util.c (revision 14664)
+++ subversion/clients/cmdline/util.c (working copy)
@@ -57,6 +57,11 @@
SVN_ERR (svn_cmdline_printf (pool, _("\nCommitted revision %ld.\n"),
commit_info->revision));
+ if ((commit_info)
+ && (commit_info->post_commit_err))
+ SVN_ERR (svn_cmdline_printf (pool, _("\nWARNING:\n%s\n"),
+ commit_info->post_commit_err));
+
return SVN_NO_ERROR;
}
Index: subversion/tests/clients/cmdline/commit_tests.py
===================================================================
--- subversion/tests/clients/cmdline/commit_tests.py (revision 14664)
+++ subversion/tests/clients/cmdline/commit_tests.py (working copy)
@@ -898,6 +898,45 @@
#----------------------------------------------------------------------
+def post_commit_hook_test(sbox):
+ "post commit hook failure case testing"
+
+ sbox.build()
+
+ # Get paths to the working copy and repository
+ wc_dir = sbox.wc_dir
+ repo_dir = sbox.repo_dir
+
+ # Setup the hook configs to echo data back
+ post_commit_hook = svntest.main.get_post_commit_hook_path (repo_dir)
+ svntest.main.file_append (post_commit_hook,
+ """#!/bin/sh
+ echo "Post-commit Hook says nothing doing on stderr" > /dev/stderr
+ exit -1
+ """)
+ os.chmod (post_commit_hook, 0755)
+
+ # Modify iota just so there is something to commit.
+ iota_path = os.path.join (wc_dir, "iota")
+ svntest.main.file_append (iota_path, "lakalakalakalaka")
+
+ # Now, commit and examine the output (we happen to know that the
+ # filesystem will report an absolute path because that's the way the
+ # filesystem is created by this test suite.
+ expected_output = [ "Sending "+ iota_path + "\n",
+ "Transmitting file data .\n",
+ "Committed revision 2.\n",
+ "\n",
+ "WARNING:\n",
+ "'post-commit' hook failed with error output:\n",
+ "Post-commit Hook says nothing doing on stderr\n",
+ "\n"]
+
+ svntest.actions.run_and_verify_svn (None, expected_output, None,
+ 'ci', '-m', 'log msg', iota_path)
+
+#----------------------------------------------------------------------
+
# Regression test for bug #469, whereby merge() was once reporting
# erroneous conflicts due to Ancestor < Target < Source, in terms of
# node-rev-id parentage.
@@ -1994,6 +2033,7 @@
mods_in_schedule_delete,
Skip(tab_test, (os.name != 'posix' or sys.platform == 'cygwin')),
local_mods_are_not_commits,
+ post_commit_hook_test,
]
if __name__ == '__main__':
Index: subversion/libsvn_repos/hooks.c
===================================================================
--- subversion/libsvn_repos/hooks.c (revision 14664)
+++ subversion/libsvn_repos/hooks.c (working copy)
@@ -297,7 +297,7 @@
args[2] = apr_psprintf (pool, "%ld", rev);
args[3] = NULL;
- SVN_ERR (run_hook_cmd ("post-commit", hook, args, FALSE, NULL, pool));
+ SVN_ERR (run_hook_cmd ("post-commit", hook, args, TRUE, NULL, pool));
}
return SVN_NO_ERROR;
Index: subversion/libsvn_repos/commit.c
===================================================================
--- subversion/libsvn_repos/commit.c (revision 14664)
+++ subversion/libsvn_repos/commit.c (working copy)
@@ -556,6 +556,7 @@
svn_revnum_t new_revision = SVN_INVALID_REVNUM;
svn_error_t *err;
const char *conflict;
+ char *post_commit_err = NULL ;
/* Commit. */
err = svn_repos_fs_commit_txn (&conflict, eb->repos,
@@ -587,16 +588,14 @@
}
else if (err)
{
- /* ### TODO: ra_local is the only RA layer that currently
- understands SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED. And as of
- at least r12960, svn_repos_fs_commit_txn() would never return
- that anyway. If someone who knows ra_svn better can add
- handling for this special case, this whole "else if" block
- can go away (again). */
+ /* retrieve the post-commit hook stderr */
+ if (err->child->message)
+ post_commit_err = apr_pstrdup (pool, err->child->message) ;
+
svn_error_clear(err);
err = SVN_NO_ERROR;
}
-
+
/* Pass new revision information to the caller's callback. */
{
svn_string_t *date, *author;
@@ -618,6 +617,7 @@
err2 = (*eb->callback) (new_revision,
date ? date->data : NULL,
author ? author->data : NULL,
+ post_commit_err,
eb->callback_baton);
if (err2)
{
Index: subversion/libsvn_ra_svn/client.c
===================================================================
--- subversion/libsvn_ra_svn/client.c (revision 14664)
+++ subversion/libsvn_ra_svn/client.c (working copy)
@@ -785,15 +785,18 @@
svn_revnum_t new_rev;
const char *committed_date;
const char *committed_author;
+ const char *post_commit_err;
SVN_ERR(handle_auth_request(ccb->sess_baton, ccb->pool));
- SVN_ERR(svn_ra_svn_read_tuple(ccb->sess_baton->conn, ccb->pool, "r(?c)(?c)",
+ SVN_ERR(svn_ra_svn_read_tuple(ccb->sess_baton->conn, ccb->pool,
+ "r(?c)(?c)(?c)",
&new_rev,
&committed_date,
- &committed_author));
+ &committed_author,
+ &post_commit_err));
return ccb->callback(new_rev, committed_date, committed_author,
- ccb->callback_baton);
+ post_commit_err, ccb->callback_baton);
}
Index: subversion/libsvn_ra_dav/merge.c
===================================================================
--- subversion/libsvn_ra_dav/merge.c (revision 14664)
+++ subversion/libsvn_ra_dav/merge.c (working copy)
@@ -58,6 +58,8 @@
{ "DAV:", "collection", ELEM_collection, 0 },
{ "DAV:", "baseline", ELEM_baseline, 0 },
{ "DAV:", "version-name", ELEM_version_name, SVN_RA_DAV__XML_CDATA },
+ { SVN_XML_NAMESPACE, "post-commit-err",
+ ELEM_post_commit_err, SVN_RA_DAV__XML_CDATA },
{ "DAV:", "creationdate", ELEM_creationdate, SVN_RA_DAV__XML_CDATA },
{ "DAV:", "creator-displayname", ELEM_creator_displayname,
SVN_RA_DAV__XML_CDATA },
@@ -104,6 +106,8 @@
svn_stringbuf_t *committed_date; /* DAV:creationdate for this resource */
svn_stringbuf_t *last_author; /* DAV:creator-displayname for this
resource */
+ svn_stringbuf_t *post_commit_err;/* SVN_XML_NAMESPACE:post-commit hook's
+ stderr */
/* We only invoke set_prop() on targets listed in valid_targets.
Some entities (such as directories that have had changes
@@ -341,6 +345,7 @@
|| child == ELEM_version_name
|| child == ELEM_creationdate
|| child == ELEM_creator_displayname
+ || child == ELEM_post_commit_err
/* other props */)
return SVN_RA_DAV__XML_VALID;
else
@@ -524,6 +529,10 @@
svn_stringbuf_set(mc->vsn_name, cdata);
break;
+ case ELEM_post_commit_err:
+ svn_stringbuf_set(mc->post_commit_err, cdata);
+ break;
+
case ELEM_creationdate:
svn_stringbuf_set(mc->committed_date, cdata);
break;
@@ -641,6 +650,7 @@
svn_revnum_t *new_rev,
const char **committed_date,
const char **committed_author,
+ const char **post_commit_err,
svn_ra_dav__session_t *ras,
const char *repos_url,
const char *activity_url,
@@ -670,6 +680,7 @@
mc.vsn_url = MAKE_BUFFER(pool);
mc.committed_date = MAKE_BUFFER(pool);
mc.last_author = MAKE_BUFFER(pool);
+ mc.post_commit_err = MAKE_BUFFER(pool);
if (disable_merge_response
|| (! keep_locks))
@@ -727,6 +738,10 @@
*committed_author = mc.last_author->len
? apr_pstrdup(pool, mc.last_author->data) : NULL;
+ if (post_commit_err)
+ *post_commit_err = mc.post_commit_err->len
+ ? apr_pstrdup(pool, mc.post_commit_err->data) : NULL;
+
svn_pool_destroy(mc.scratchpool);
return NULL;
Index: subversion/libsvn_ra_dav/ra_dav.h
===================================================================
--- subversion/libsvn_ra_dav/ra_dav.h (revision 14664)
+++ subversion/libsvn_ra_dav/ra_dav.h (working copy)
@@ -654,6 +654,7 @@
ELEM_updated_set,
ELEM_vcc,
ELEM_version_name,
+ ELEM_post_commit_err,
ELEM_error,
/* SVN elements */
@@ -708,6 +709,7 @@
svn_revnum_t *new_rev,
const char **committed_date,
const char **committed_author,
+ const char **post_commit_err,
svn_ra_dav__session_t *ras,
const char *repos_url,
const char *activity_url,
Index: subversion/libsvn_ra_dav/commit.c
===================================================================
--- subversion/libsvn_ra_dav/commit.c (revision 14664)
+++ subversion/libsvn_ra_dav/commit.c (working copy)
@@ -1423,10 +1423,12 @@
svn_revnum_t new_rev;
const char *committed_date;
const char *committed_author;
+ const char *post_commit_err;
SVN_ERR( svn_ra_dav__merge_activity(&new_rev,
&committed_date,
&committed_author,
+ &post_commit_err,
cc->ras,
cc->ras->root.path,
cc->activity_url,
@@ -1440,7 +1442,7 @@
if (new_rev != SVN_INVALID_REVNUM)
SVN_ERR( cc->callback (new_rev, committed_date, committed_author,
- cc->callback_baton));
+ post_commit_err, cc->callback_baton));
return SVN_NO_ERROR;
}
Index: subversion/svnserve/serve.c
===================================================================
--- subversion/svnserve/serve.c (revision 14664)
+++ subversion/svnserve/serve.c (working copy)
@@ -62,6 +62,7 @@
svn_revnum_t *new_rev;
const char **date;
const char **author;
+ const char **post_commit_err;
} commit_callback_baton_t;
typedef struct {
@@ -622,13 +623,15 @@
}
static svn_error_t *commit_done(svn_revnum_t new_rev, const char *date,
- const char *author, void *baton)
+ const char *author, const char *post_commit_err,
+ void *baton)
{
commit_callback_baton_t *ccb = baton;
*ccb->new_rev = new_rev;
*ccb->date = date;
*ccb->author = author;
+ *ccb->post_commit_err = post_commit_err;
return SVN_NO_ERROR;
}
@@ -722,7 +725,7 @@
apr_array_header_t *params, void *baton)
{
server_baton_t *b = baton;
- const char *log_msg, *date, *author;
+ const char *log_msg, *date, *author, *post_commit_err;
apr_array_header_t *lock_tokens;
svn_boolean_t keep_locks;
const svn_delta_editor_t *editor;
@@ -751,6 +754,7 @@
ccb.new_rev = &new_rev;
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_editor2
(&editor, &edit_baton, b->repos, NULL,
@@ -775,8 +779,8 @@
if (! keep_locks && lock_tokens)
SVN_ERR(unlock_paths(lock_tokens, b, pool));
- SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "r(?c)(?c)",
- new_rev, date, author));
+ SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "r(?c)(?c)(?c)",
+ new_rev, date, author, post_commit_err));
if (! b->tunnel)
SVN_ERR(svn_fs_deltify_revision(b->fs, new_rev, pool));