📄 commit.c
字号:
return SVN_NO_ERROR;}static svn_error_t *open_file(const char *path, void *parent_baton, svn_revnum_t base_revision, apr_pool_t *file_pool, void **file_baton){ dir_context_t *ctx = parent_baton; file_context_t *new_file; new_file = apr_pcalloc(file_pool, sizeof(*new_file)); new_file->pool = file_pool; ctx->ref_count++; new_file->parent_dir = ctx; new_file->commit = ctx->commit; /* TODO: Remove directory names? */ new_file->name = path; new_file->base_revision = base_revision; new_file->changed_props = apr_hash_make(new_file->pool); new_file->removed_props = apr_hash_make(new_file->pool); /* CHECKOUT the file into our activity. */ SVN_ERR(checkout_file(new_file)); new_file->put_url = new_file->checkout->resource_url; *file_baton = new_file; return SVN_NO_ERROR;}static svn_error_t *apply_textdelta(void *file_baton, const char *base_checksum, apr_pool_t *pool, svn_txdelta_window_handler_t *handler, void **handler_baton){ file_context_t *ctx = file_baton; const svn_ra_callbacks2_t *wc_callbacks; void *wc_callback_baton; /* Store the stream in a temporary file; we'll give it to serf when we * close this file. * * TODO: There should be a way we can stream the request body instead of * writing to a temporary file (ugh). A special svn stream serf bucket * that returns EAGAIN until we receive the done call? But, when * would we run through the serf context? Grr. */ wc_callbacks = ctx->commit->session->wc_callbacks; wc_callback_baton = ctx->commit->session->wc_callback_baton; SVN_ERR(wc_callbacks->open_tmp_file(&ctx->svndiff, wc_callback_baton, ctx->pool)); ctx->stream = svn_stream_create(ctx, pool); svn_stream_set_write(ctx->stream, svndiff_stream_write); svn_txdelta_to_svndiff(ctx->stream, pool, handler, handler_baton); ctx->base_checksum = base_checksum; return SVN_NO_ERROR;}static svn_error_t *change_file_prop(void *file_baton, const char *name, const svn_string_t *value, apr_pool_t *pool){ file_context_t *file = file_baton; const char *ns; name = apr_pstrdup(file->pool, name); if (strncmp(name, SVN_PROP_PREFIX, sizeof(SVN_PROP_PREFIX) - 1) == 0) { ns = SVN_DAV_PROP_NS_SVN; name += sizeof(SVN_PROP_PREFIX) - 1; } else { ns = SVN_DAV_PROP_NS_CUSTOM; } if (value) { value = svn_string_dup(value, file->pool); svn_ra_serf__set_prop(file->changed_props, file->put_url, ns, name, value, file->pool); } else { value = svn_string_create("", file->pool); svn_ra_serf__set_prop(file->removed_props, file->put_url, ns, name, value, file->pool); } return SVN_NO_ERROR;}static svn_error_t *close_file(void *file_baton, const char *text_checksum, apr_pool_t *pool){ file_context_t *ctx = file_baton; ctx->result_checksum = text_checksum; if (ctx->copy_path) { svn_ra_serf__handler_t *handler; svn_ra_serf__simple_request_context_t *copy_ctx; apr_uri_t uri; apr_hash_t *props; const char *vcc_url, *rel_copy_path, *basecoll_url, *req_url; props = apr_hash_make(pool); apr_uri_parse(pool, ctx->copy_path, &uri); SVN_ERR(svn_ra_serf__discover_root(&vcc_url, &rel_copy_path, ctx->commit->session, ctx->commit->conn, uri.path, pool)); SVN_ERR(svn_ra_serf__retrieve_props(props, ctx->commit->session, ctx->commit->conn, vcc_url, ctx->copy_revision, "0", baseline_props, pool)); basecoll_url = svn_ra_serf__get_ver_prop(props, vcc_url, ctx->copy_revision, "DAV:", "baseline-collection"); if (!basecoll_url) { abort(); } req_url = svn_path_url_add_component(basecoll_url, rel_copy_path, pool); handler = apr_pcalloc(pool, sizeof(*handler)); handler->method = "COPY"; handler->path = req_url; handler->conn = ctx->commit->conn; handler->session = ctx->commit->session; copy_ctx = apr_pcalloc(pool, sizeof(*copy_ctx)); handler->response_handler = svn_ra_serf__handle_status_only; handler->response_baton = copy_ctx; handler->header_delegate = setup_copy_file_headers; handler->header_delegate_baton = ctx; svn_ra_serf__request_create(handler); SVN_ERR(svn_ra_serf__context_run_wait(©_ctx->done, ctx->commit->session, pool)); if (copy_ctx->status != 201 && copy_ctx->status != 204) { return return_response_err(handler, copy_ctx); } } /* If we had a stream of changes, push them to the server... */ if (ctx->stream) { svn_ra_serf__handler_t *handler; svn_ra_serf__simple_request_context_t *put_ctx; handler = apr_pcalloc(pool, sizeof(*handler)); handler->method = "PUT"; handler->path = ctx->put_url; handler->conn = ctx->commit->conn; handler->session = ctx->commit->session; put_ctx = apr_pcalloc(pool, sizeof(*put_ctx)); handler->response_handler = svn_ra_serf__handle_status_only; handler->response_baton = put_ctx; handler->body_delegate = create_put_body; handler->body_delegate_baton = ctx; handler->body_type = "application/vnd.svn-svndiff"; handler->header_delegate = setup_put_headers; handler->header_delegate_baton = ctx; svn_ra_serf__request_create(handler); SVN_ERR(svn_ra_serf__context_run_wait(&put_ctx->done, ctx->commit->session, pool)); if (put_ctx->status != 204 && put_ctx->status != 201) { return return_response_err(handler, put_ctx); } } /* If we had any prop changes, push them via PROPPATCH. */ if (apr_hash_count(ctx->changed_props) || apr_hash_count(ctx->removed_props)) { proppatch_context_t *proppatch; proppatch = apr_pcalloc(ctx->pool, sizeof(*proppatch)); proppatch->pool = ctx->pool; proppatch->name = ctx->name; proppatch->path = ctx->put_url; proppatch->commit = ctx->commit; proppatch->changed_props = ctx->changed_props; proppatch->removed_props = ctx->removed_props; SVN_ERR(proppatch_resource(proppatch, ctx->commit, ctx->pool)); } return SVN_NO_ERROR;}static svn_error_t *absent_file(const char *path, void *parent_baton, apr_pool_t *pool){#if 0 dir_context_t *ctx = parent_baton;#endif abort();}static svn_error_t *close_edit(void *edit_baton, apr_pool_t *pool){ commit_context_t *ctx = edit_baton; svn_ra_serf__merge_context_t *merge_ctx; svn_ra_serf__simple_request_context_t *delete_ctx; svn_ra_serf__handler_t *handler; svn_boolean_t *merge_done; /* MERGE our activity */ SVN_ERR(svn_ra_serf__merge_create_req(&merge_ctx, ctx->session, ctx->session->conns[0], ctx->session->repos_url.path, ctx->activity_url, ctx->activity_url_len, ctx->lock_tokens, ctx->keep_locks, pool)); merge_done = svn_ra_serf__merge_get_done_ptr(merge_ctx); SVN_ERR(svn_ra_serf__context_run_wait(merge_done, ctx->session, pool)); if (svn_ra_serf__merge_get_status(merge_ctx) != 200) { abort(); } /* Inform the WC that we did a commit. */ SVN_ERR(ctx->callback(svn_ra_serf__merge_get_commit_info(merge_ctx), ctx->callback_baton, pool)); /* DELETE our completed activity */ handler = apr_pcalloc(pool, sizeof(*handler)); handler->method = "DELETE"; handler->path = ctx->activity_url; handler->conn = ctx->conn; handler->session = ctx->session; delete_ctx = apr_pcalloc(pool, sizeof(*delete_ctx)); handler->response_handler = svn_ra_serf__handle_status_only; handler->response_baton = delete_ctx; svn_ra_serf__request_create(handler); SVN_ERR(svn_ra_serf__context_run_wait(&delete_ctx->done, ctx->session, pool)); if (delete_ctx->status != 204) { abort(); } return SVN_NO_ERROR;}static svn_error_t *abort_edit(void *edit_baton, apr_pool_t *pool){ commit_context_t *ctx = edit_baton; svn_ra_serf__handler_t *handler; svn_ra_serf__simple_request_context_t *delete_ctx; /* DELETE our aborted activity */ handler = apr_pcalloc(pool, sizeof(*handler)); handler->method = "DELETE"; handler->path = ctx->activity_url; handler->conn = ctx->session->conns[0]; handler->session = ctx->session; delete_ctx = apr_pcalloc(pool, sizeof(*delete_ctx)); handler->response_handler = svn_ra_serf__handle_status_only; handler->response_baton = delete_ctx; svn_ra_serf__request_create(handler); SVN_ERR(svn_ra_serf__context_run_wait(&delete_ctx->done, ctx->session, pool)); if (delete_ctx->status != 204) { abort(); } return SVN_NO_ERROR;}svn_error_t *svn_ra_serf__get_commit_editor(svn_ra_session_t *ra_session, const svn_delta_editor_t **ret_editor, void **edit_baton, const char *log_msg, svn_commit_callback2_t callback, void *callback_baton, apr_hash_t *lock_tokens, svn_boolean_t keep_locks, apr_pool_t *pool){ svn_ra_serf__session_t *session = ra_session->priv; svn_delta_editor_t *editor; commit_context_t *ctx; ctx = apr_pcalloc(pool, sizeof(*ctx)); ctx->pool = pool; ctx->session = session; ctx->conn = session->conns[0]; ctx->log_msg = svn_string_create(log_msg, pool); ctx->callback = callback; ctx->callback_baton = callback_baton; ctx->lock_tokens = lock_tokens; ctx->keep_locks = keep_locks; ctx->deleted_entries = apr_hash_make(ctx->pool); ctx->copied_entries = apr_hash_make(ctx->pool); editor = svn_delta_default_editor(pool); editor->open_root = open_root; editor->delete_entry = delete_entry; editor->add_directory = add_directory; editor->open_directory = open_directory; editor->change_dir_prop = change_dir_prop; editor->close_directory = close_directory; editor->absent_directory = absent_directory; editor->add_file = add_file; editor->open_file = open_file; editor->apply_textdelta = apply_textdelta; editor->change_file_prop = change_file_prop; editor->close_file = close_file; editor->absent_file = absent_file; editor->close_edit = close_edit; editor->abort_edit = abort_edit; *ret_editor = editor; *edit_baton = ctx; return SVN_NO_ERROR;}svn_error_t *svn_ra_serf__change_rev_prop(svn_ra_session_t *ra_session, svn_revnum_t rev, const char *name, const svn_string_t *value, apr_pool_t *pool){ svn_ra_serf__session_t *session = ra_session->priv; svn_ra_serf__propfind_context_t *propfind_ctx; proppatch_context_t *proppatch_ctx; commit_context_t *commit; const char *vcc_url, *checked_in_href, *ns; apr_hash_t *props; commit = apr_pcalloc(pool, sizeof(*commit)); commit->pool = pool; commit->session = session; commit->conn = session->conns[0]; SVN_ERR(svn_ra_serf__discover_root(&vcc_url, NULL, commit->session, commit->conn, commit->session->repos_url.path, pool)); props = apr_hash_make(pool); propfind_ctx = NULL; svn_ra_serf__deliver_props(&propfind_ctx, props, commit->session, commit->conn, vcc_url, rev, "0", checked_in_props, FALSE, NULL, pool); SVN_ERR(svn_ra_serf__wait_for_props(propfind_ctx, commit->session, pool)); checked_in_href = svn_ra_serf__get_ver_prop(props, vcc_url, rev, "DAV:", "href"); if (strncmp(name, SVN_PROP_PREFIX, sizeof(SVN_PROP_PREFIX) - 1) == 0) { ns = SVN_DAV_PROP_NS_SVN; name += sizeof(SVN_PROP_PREFIX) - 1; } else { ns = SVN_DAV_PROP_NS_CUSTOM; } /* PROPPATCH our log message and pass it along. */ proppatch_ctx = apr_pcalloc(pool, sizeof(*proppatch_ctx)); proppatch_ctx->pool = pool; proppatch_ctx->commit = commit; proppatch_ctx->path = checked_in_href; proppatch_ctx->changed_props = apr_hash_make(proppatch_ctx->pool); proppatch_ctx->removed_props = apr_hash_make(proppatch_ctx->pool); if (value) { svn_ra_serf__set_prop(proppatch_ctx->changed_props, proppatch_ctx->path, ns, name, value, proppatch_ctx->pool); } else { value = svn_string_create("", proppatch_ctx->pool); svn_ra_serf__set_prop(proppatch_ctx->removed_props, proppatch_ctx->path, ns, name, value, proppatch_ctx->pool); } SVN_ERR(proppatch_resource(proppatch_ctx, commit, proppatch_ctx->pool)); return SVN_NO_ERROR;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -