summaryrefslogtreecommitdiff
path: root/subversion/libsvn_ra_serf/merge.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_ra_serf/merge.c')
-rw-r--r--subversion/libsvn_ra_serf/merge.c82
1 files changed, 54 insertions, 28 deletions
diff --git a/subversion/libsvn_ra_serf/merge.c b/subversion/libsvn_ra_serf/merge.c
index 670e421..0a2fd54 100644
--- a/subversion/libsvn_ra_serf/merge.c
+++ b/subversion/libsvn_ra_serf/merge.c
@@ -48,7 +48,7 @@
* This enum represents the current state of our XML parsing for a MERGE.
*/
typedef enum merge_state_e {
- INITIAL = 0,
+ INITIAL = XML_STATE_INITIAL,
MERGE_RESPONSE,
UPDATED_SET,
RESPONSE,
@@ -65,7 +65,7 @@ typedef enum merge_state_e {
AUTHOR,
POST_COMMIT_ERR,
- PROP_VAL
+ STATUS
} merge_state_e;
@@ -171,7 +171,12 @@ merge_closed(svn_ra_serf__xml_estate_t *xes,
rev_str = svn_hash_gets(attrs, "revision");
if (rev_str)
- merge_ctx->commit_info->revision = SVN_STR_TO_REV(rev_str);
+ {
+ apr_int64_t rev;
+
+ SVN_ERR(svn_cstring_atoi64(&rev, rev_str));
+ merge_ctx->commit_info->revision = (svn_revnum_t)rev;
+ }
else
merge_ctx->commit_info->revision = SVN_INVALID_REVNUM;
@@ -266,7 +271,8 @@ merge_closed(svn_ra_serf__xml_estate_t *xes,
static svn_error_t *
setup_merge_headers(serf_bucket_t *headers,
void *baton,
- apr_pool_t *pool)
+ apr_pool_t *pool /* request pool */,
+ apr_pool_t *scratch_pool)
{
merge_context_t *ctx = baton;
@@ -294,7 +300,7 @@ svn_ra_serf__merge_lock_token_list(apr_hash_t *lock_tokens,
svn_ra_serf__add_open_tag_buckets(body, alloc,
"S:lock-token-list",
"xmlns:S", SVN_XML_NAMESPACE,
- NULL);
+ SVN_VA_NULL);
for (hi = apr_hash_first(pool, lock_tokens);
hi;
@@ -313,9 +319,9 @@ svn_ra_serf__merge_lock_token_list(apr_hash_t *lock_tokens,
if (parent && !svn_relpath_skip_ancestor(parent, key))
continue;
- svn_ra_serf__add_open_tag_buckets(body, alloc, "S:lock", NULL);
+ svn_ra_serf__add_open_tag_buckets(body, alloc, "S:lock", SVN_VA_NULL);
- svn_ra_serf__add_open_tag_buckets(body, alloc, "lock-path", NULL);
+ svn_ra_serf__add_open_tag_buckets(body, alloc, "lock-path", SVN_VA_NULL);
svn_ra_serf__add_cdata_len_buckets(body, alloc, path.data, path.len);
svn_ra_serf__add_close_tag_buckets(body, alloc, "lock-path");
@@ -327,11 +333,13 @@ svn_ra_serf__merge_lock_token_list(apr_hash_t *lock_tokens,
svn_ra_serf__add_close_tag_buckets(body, alloc, "S:lock-token-list");
}
+/* Implements svn_ra_serf__request_body_delegate_t */
static svn_error_t*
create_merge_body(serf_bucket_t **bkt,
void *baton,
serf_bucket_alloc_t *alloc,
- apr_pool_t *pool)
+ apr_pool_t *pool /* request pool */,
+ apr_pool_t *scratch_pool)
{
merge_context_t *ctx = baton;
serf_bucket_t *body_bkt;
@@ -341,9 +349,9 @@ create_merge_body(serf_bucket_t **bkt,
svn_ra_serf__add_xml_header_buckets(body_bkt, alloc);
svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:merge",
"xmlns:D", "DAV:",
- NULL);
- svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:source", NULL);
- svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:href", NULL);
+ SVN_VA_NULL);
+ svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:source", SVN_VA_NULL);
+ svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:href", SVN_VA_NULL);
svn_ra_serf__add_cdata_len_buckets(body_bkt, alloc,
ctx->merge_resource_url,
@@ -352,19 +360,26 @@ create_merge_body(serf_bucket_t **bkt,
svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:href");
svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:source");
- svn_ra_serf__add_tag_buckets(body_bkt, "D:no-auto-merge", NULL, alloc);
- svn_ra_serf__add_tag_buckets(body_bkt, "D:no-checkout", NULL, alloc);
-
- svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:prop", NULL);
- svn_ra_serf__add_tag_buckets(body_bkt, "D:checked-in", NULL, alloc);
- svn_ra_serf__add_tag_buckets(body_bkt, "D:" SVN_DAV__VERSION_NAME, NULL, alloc);
- svn_ra_serf__add_tag_buckets(body_bkt, "D:resourcetype", NULL, alloc);
- svn_ra_serf__add_tag_buckets(body_bkt, "D:" SVN_DAV__CREATIONDATE, NULL, alloc);
- svn_ra_serf__add_tag_buckets(body_bkt, "D:creator-displayname", NULL, alloc);
+ svn_ra_serf__add_empty_tag_buckets(body_bkt, alloc,
+ "D:no-auto-merge", SVN_VA_NULL);
+ svn_ra_serf__add_empty_tag_buckets(body_bkt, alloc,
+ "D:no-checkout", SVN_VA_NULL);
+
+ svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:prop", SVN_VA_NULL);
+ svn_ra_serf__add_empty_tag_buckets(body_bkt, alloc,
+ "D:checked-in", SVN_VA_NULL);
+ svn_ra_serf__add_empty_tag_buckets(body_bkt, alloc,
+ "D:" SVN_DAV__VERSION_NAME, SVN_VA_NULL);
+ svn_ra_serf__add_empty_tag_buckets(body_bkt, alloc,
+ "D:resourcetype", SVN_VA_NULL);
+ svn_ra_serf__add_empty_tag_buckets(body_bkt, alloc,
+ "D:" SVN_DAV__CREATIONDATE, SVN_VA_NULL);
+ svn_ra_serf__add_empty_tag_buckets(body_bkt, alloc,
+ "D:creator-displayname", SVN_VA_NULL);
svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:prop");
- svn_ra_serf__merge_lock_token_list(ctx->lock_tokens, NULL, body_bkt, alloc,
- pool);
+ svn_ra_serf__merge_lock_token_list(ctx->lock_tokens, NULL, body_bkt,
+ alloc, pool);
svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:merge");
@@ -376,9 +391,7 @@ create_merge_body(serf_bucket_t **bkt,
svn_error_t *
svn_ra_serf__run_merge(const svn_commit_info_t **commit_info,
- int *response_code,
svn_ra_serf__session_t *session,
- svn_ra_serf__connection_t *conn,
const char *merge_resource_url,
apr_hash_t *lock_tokens,
svn_boolean_t keep_locks,
@@ -407,14 +420,14 @@ svn_ra_serf__run_merge(const svn_commit_info_t **commit_info,
NULL, merge_closed, NULL,
merge_ctx,
scratch_pool);
- handler = svn_ra_serf__create_expat_handler(xmlctx, scratch_pool);
+ handler = svn_ra_serf__create_expat_handler(session, xmlctx, NULL,
+ scratch_pool);
handler->method = "MERGE";
handler->path = merge_ctx->merge_url;
handler->body_delegate = create_merge_body;
handler->body_delegate_baton = merge_ctx;
- handler->conn = conn;
- handler->session = session;
+ handler->body_type = "text/xml";
handler->header_delegate = setup_merge_headers;
handler->header_delegate_baton = merge_ctx;
@@ -423,8 +436,21 @@ svn_ra_serf__run_merge(const svn_commit_info_t **commit_info,
SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));
+ if (handler->sline.code != 200)
+ return svn_error_trace(svn_ra_serf__unexpected_status(handler));
+
*commit_info = merge_ctx->commit_info;
- *response_code = handler->sline.code;
+
+ /* Sanity check (Reported to be triggered by CodePlex's svnbridge) */
+ if (! SVN_IS_VALID_REVNUM(merge_ctx->commit_info->revision))
+ {
+ return svn_error_create(SVN_ERR_RA_DAV_PROPS_NOT_FOUND, NULL,
+ _("The MERGE response did not include "
+ "a new revision"));
+ }
+
+ merge_ctx->commit_info->repos_root = apr_pstrdup(result_pool,
+ session->repos_root_str);
return SVN_NO_ERROR;
}