📄 commit.c
字号:
apr_hash_t *props; props = apr_hash_make(dir->pool); propfind_ctx = NULL; svn_ra_serf__deliver_props(&propfind_ctx, props, session, dir->commit->conn, session->repos_url.path, dir->base_revision, "0", checked_in_props, FALSE, NULL, dir->pool); SVN_ERR(svn_ra_serf__wait_for_props(propfind_ctx, session, dir->pool)); root_checkout = svn_ra_serf__get_ver_prop(props, session->repos_url.path, dir->base_revision, "DAV:", "checked-in"); } dir->checked_in_url = svn_path_url_add_component(root_checkout, dir->name, dir->pool); return SVN_NO_ERROR;}static svn_error_t *proppatch_walker(void *baton, const char *ns, apr_ssize_t ns_len, const char *name, apr_ssize_t name_len, const svn_string_t *val, apr_pool_t *pool){ serf_bucket_t *body_bkt = baton; serf_bucket_t *tmp_bkt; serf_bucket_alloc_t *alloc; svn_boolean_t binary_prop; if (svn_xml_is_xml_safe(val->data, val->len)) { binary_prop = FALSE; } else { binary_prop = TRUE; } alloc = body_bkt->allocator; tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN("<", sizeof("<") - 1, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN(name, name_len, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN(" xmlns=\"", sizeof(" xmlns=\"") - 1, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN(ns, ns_len, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); if (binary_prop == TRUE) { tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN("\" V:encoding=\"base64", sizeof("\" V:encoding=\"base64") - 1, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); } tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN("\">", sizeof("\">") - 1, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); if (binary_prop == TRUE) { val = svn_base64_encode_string(val, pool); } else { svn_stringbuf_t *prop_buf = svn_stringbuf_create("", pool); svn_xml_escape_cdata_string(&prop_buf, val, pool); val = svn_string_create_from_buf(prop_buf, pool); } tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN(val->data, val->len, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN("</", sizeof("</") - 1, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN(name, name_len, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN(">", sizeof(">") - 1, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); return SVN_NO_ERROR;}static apr_status_tsetup_proppatch_headers(serf_bucket_t *headers, void *baton, apr_pool_t *pool){ proppatch_context_t *proppatch = baton; if (proppatch->name && proppatch->commit->lock_tokens) { const char *token; token = apr_hash_get(proppatch->commit->lock_tokens, proppatch->name, APR_HASH_KEY_STRING); if (token) { const char *token_header; token_header = apr_pstrcat(pool, "(<", token, ">)", NULL); serf_bucket_headers_set(headers, "If", token_header); } } return APR_SUCCESS;}#define PROPPATCH_HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?><D:propertyupdate xmlns:D=\"DAV:\" xmlns:V=\"" SVN_DAV_PROP_NS_DAV "\">"#define PROPPATCH_TRAILER "</D:propertyupdate>"static serf_bucket_t *create_proppatch_body(void *baton, serf_bucket_alloc_t *alloc, apr_pool_t *pool){ proppatch_context_t *ctx = baton; serf_bucket_t *body_bkt, *tmp_bkt; body_bkt = serf_bucket_aggregate_create(alloc); tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN(PROPPATCH_HEADER, sizeof(PROPPATCH_HEADER) - 1, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); if (apr_hash_count(ctx->changed_props) > 0) { tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN("<D:set>", sizeof("<D:set>") - 1, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN("<D:prop>", sizeof("<D:prop>") - 1, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); svn_ra_serf__walk_all_props(ctx->changed_props, ctx->path, SVN_INVALID_REVNUM, proppatch_walker, body_bkt, pool); tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN("</D:prop>", sizeof("</D:prop>") - 1, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN("</D:set>", sizeof("</D:set>") - 1, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); } if (apr_hash_count(ctx->removed_props) > 0) { tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN("<D:remove>", sizeof("<D:remove>") - 1, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN("<D:prop>", sizeof("<D:prop>") - 1, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); svn_ra_serf__walk_all_props(ctx->removed_props, ctx->path, SVN_INVALID_REVNUM, proppatch_walker, body_bkt, pool); tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN("</D:prop>", sizeof("</D:prop>") - 1, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN("</D:remove>", sizeof("</D:remove>") - 1, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); } tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN(PROPPATCH_TRAILER, sizeof(PROPPATCH_TRAILER) - 1, alloc); serf_bucket_aggregate_append(body_bkt, tmp_bkt); return body_bkt;}static svn_error_t*proppatch_resource(proppatch_context_t *proppatch, commit_context_t *commit, apr_pool_t *pool){ svn_ra_serf__handler_t *handler; handler = apr_pcalloc(pool, sizeof(*handler)); handler->method = "PROPPATCH"; handler->path = proppatch->path; handler->conn = commit->conn; handler->session = commit->session; handler->header_delegate = setup_proppatch_headers; handler->header_delegate_baton = proppatch; handler->body_delegate = create_proppatch_body; handler->body_delegate_baton = proppatch; handler->response_handler = svn_ra_serf__handle_status_only; handler->response_baton = &proppatch->progress; svn_ra_serf__request_create(handler); /* If we don't wait for the response, our pool will be gone! */ SVN_ERR(svn_ra_serf__context_run_wait(&proppatch->progress.done, commit->session, pool)); if (proppatch->progress.status != 207) { svn_error_t *err; err = return_response_err(handler, &proppatch->progress); return svn_error_create(SVN_ERR_RA_DAV_PROPPATCH_FAILED, err, _("At least one property change failed; repository is unchanged")); } return SVN_NO_ERROR;}static serf_bucket_t *create_put_body(void *baton, serf_bucket_alloc_t *alloc, apr_pool_t *pool){ file_context_t *ctx = baton; apr_off_t offset; /* We need to flush the file, make it unbuffered (so that it can be * zero-copied via mmap), and reset the position before attempting to * deliver the file. * * N.B. On older APR versions, we can't check the buffer status; but serf * will fall through and create a file bucket for us on the buffered svndiff * handle. */ apr_file_flush(ctx->svndiff); offset = 0; apr_file_seek(ctx->svndiff, APR_SET, &offset); return serf_bucket_file_create(ctx->svndiff, alloc);}static apr_status_tsetup_put_headers(serf_bucket_t *headers, void *baton, apr_pool_t *pool){ file_context_t *ctx = baton; if (ctx->base_checksum) { serf_bucket_headers_set(headers, SVN_DAV_BASE_FULLTEXT_MD5_HEADER, ctx->base_checksum); } if (ctx->result_checksum) { serf_bucket_headers_set(headers, SVN_DAV_RESULT_FULLTEXT_MD5_HEADER, ctx->result_checksum); } if (ctx->commit->lock_tokens) { const char *token; token = apr_hash_get(ctx->commit->lock_tokens, ctx->name, APR_HASH_KEY_STRING); if (token) { const char *token_header; token_header = apr_pstrcat(pool, "(<", token, ">)", NULL); serf_bucket_headers_set(headers, "If", token_header); } } return APR_SUCCESS;}static apr_status_tsetup_copy_file_headers(serf_bucket_t *headers, void *baton, apr_pool_t *pool){ file_context_t *file = baton; apr_uri_t uri; const char *absolute_uri; /* The Dest URI must be absolute. Bummer. */ uri = file->commit->session->repos_url; uri.path = (char*)file->put_url; absolute_uri = apr_uri_unparse(pool, &uri, 0); serf_bucket_headers_set(headers, "Destination", absolute_uri); serf_bucket_headers_set(headers, "Depth", "0"); serf_bucket_headers_set(headers, "Overwrite", "T"); return APR_SUCCESS;}static apr_status_tsetup_copy_dir_headers(serf_bucket_t *headers, void *baton, apr_pool_t *pool){ dir_context_t *dir = baton; apr_uri_t uri; const char *absolute_uri; /* The Dest URI must be absolute. Bummer. */ uri = dir->commit->session->repos_url; uri.path = (char*)svn_path_url_add_component(dir->parent_dir->checkout->resource_url, svn_path_basename(dir->name, pool), pool); absolute_uri = apr_uri_unparse(pool, &uri, 0); serf_bucket_headers_set(headers, "Destination", absolute_uri); serf_bucket_headers_set(headers, "Depth", "infinity"); serf_bucket_headers_set(headers, "Overwrite", "T"); /* Implicitly checkout this dir now. */ dir->checkout = apr_pcalloc(dir->pool, sizeof(*dir->checkout)); dir->checkout->pool = dir->pool; dir->checkout->activity_url = dir->commit->activity_url; dir->checkout->activity_url_len = dir->commit->activity_url_len; dir->checkout->resource_url = apr_pstrdup(dir->checkout->pool, uri.path); apr_hash_set(dir->commit->copied_entries, apr_pstrdup(dir->commit->pool, dir->name), APR_HASH_KEY_STRING, (void*)1); return APR_SUCCESS;}static apr_status_tsetup_delete_headers(serf_bucket_t *headers, void *baton, apr_pool_t *pool){ delete_context_t *ctx = baton; serf_bucket_headers_set(headers, SVN_DAV_VERSION_NAME_HEADER, apr_ltoa(pool, ctx->revision)); if (ctx->lock_token_hash) { ctx->lock_token = apr_hash_get(ctx->lock_token_hash, ctx->path, APR_HASH_KEY_STRING); if (ctx->lock_token) { const char *token_header; token_header = apr_pstrcat(pool, "<", ctx->path, "> (<", ctx->lock_token, ">)", NULL); serf_bucket_headers_set(headers, "If", token_header); if (ctx->keep_locks) serf_bucket_headers_set(headers, SVN_DAV_OPTIONS_HEADER, SVN_DAV_OPTION_KEEP_LOCKS); } } return APR_SUCCESS;}#define XML_HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?>"static serf_bucket_t *create_delete_body(void *baton, serf_bucket_alloc_t *alloc, apr_pool_t *pool){ delete_context_t *ctx = baton; serf_bucket_t *body, *tmp; body = serf_bucket_aggregate_create(alloc); tmp = SERF_BUCKET_SIMPLE_STRING_LEN(XML_HEADER, sizeof(XML_HEADER) - 1, alloc); serf_bucket_aggregate_append(body, tmp); svn_ra_serf__merge_lock_token_list(ctx->lock_token_hash, ctx->path, body, alloc, pool); return body;}/* Helper function to write the svndiff stream to temporary file. */static svn_error_t *svndiff_stream_write(void *file_baton, const char *data, apr_size_t *len){ file_context_t *ctx = file_baton; apr_status_t status; status = apr_file_write_full(ctx->svndiff, data, *len, NULL); if (status) return svn_error_wrap_apr(status, _("Failed writing updated file")); return SVN_NO_ERROR;}/* Commit baton callbacks */static svn_error_t *open_root(void *edit_baton, svn_revnum_t base_revision, apr_pool_t *dir_pool, void **root_baton){ commit_context_t *ctx = edit_baton; svn_ra_serf__options_context_t *opt_ctx; svn_ra_serf__propfind_context_t *propfind_ctx; svn_ra_serf__handler_t *handler; svn_ra_serf__simple_request_context_t *mkact_ctx; proppatch_context_t *proppatch_ctx; dir_context_t *dir; const char *activity_str; const char *vcc_url; apr_hash_t *props; /* Create a UUID for this commit. */ ctx->uuid = svn_uuid_generate(ctx->pool);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -