⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 commit.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * commit.c :  entry point for commit RA functions for ra_serf * * ==================================================================== * Copyright (c) 2006 CollabNet.  All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution.  The terms * are also available at http://subversion.tigris.org/license-1.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * * This software consists of voluntary contributions made by many * individuals.  For exact contribution history, see the revision * history and logs, available at http://subversion.tigris.org/. * ==================================================================== */#include <apr_uri.h>#include <expat.h>#include <serf.h>#include "svn_pools.h"#include "svn_ra.h"#include "svn_dav.h"#include "svn_xml.h"#include "../libsvn_ra/ra_loader.h"#include "svn_config.h"#include "svn_delta.h"#include "svn_base64.h"#include "svn_version.h"#include "svn_path.h"#include "svn_private_config.h"#include "ra_serf.h"/* Structure associated with a CHECKOUT request. */typedef struct {  apr_pool_t *pool;  const char *activity_url;  apr_size_t activity_url_len;  const char *checkout_url;  const char *resource_url;  svn_ra_serf__simple_request_context_t progress;} checkout_context_t;/* Baton passed back with the commit editor. */typedef struct {  /* Pool for our commit. */  apr_pool_t *pool;  svn_ra_serf__session_t *session;  svn_ra_serf__connection_t *conn;  svn_string_t *log_msg;  svn_commit_callback2_t callback;  void *callback_baton;  apr_hash_t *lock_tokens;  svn_boolean_t keep_locks;  const char *uuid;  const char *activity_url;  apr_size_t activity_url_len;  /* The checkout for the baseline. */  checkout_context_t *baseline;  /* The checked-in root to base CHECKOUTs from */  const char *checked_in_url;   /* The root baseline collection */   const char *baseline_url;  /* Deleted files - so we can detect delete+add (replace) ops. */  apr_hash_t *deleted_entries;  /* Copied entries - so we do not checkout these resources. */  apr_hash_t *copied_entries;} commit_context_t;/* Structure associated with a PROPPATCH request. */typedef struct {  apr_pool_t *pool;  const char *name;  const char *path;  commit_context_t *commit;  /* Changed and removed properties. */  apr_hash_t *changed_props;  apr_hash_t *removed_props;  svn_ra_serf__simple_request_context_t progress;} proppatch_context_t;typedef struct {  const char *path;  svn_revnum_t revision;  const char *lock_token;  apr_hash_t *lock_token_hash;  svn_boolean_t keep_locks;  svn_ra_serf__simple_request_context_t progress;} delete_context_t;/* Represents a directory. */typedef struct dir_context_t {  /* Pool for our directory. */  apr_pool_t *pool;  /* The root commit we're in progress for. */  commit_context_t *commit;  /* The checked out context for this directory.   *   * May be NULL; if so call checkout_dir() first.   */  checkout_context_t *checkout;  /* Our URL to CHECKOUT */  const char *checked_in_url;  /* How many pending changes we have left in this directory. */  unsigned int ref_count;  /* Our parent */  struct dir_context_t *parent_dir;  /* The directory name; if NULL, we're the 'root' */  const char *name;  /* The base revision of the dir. */  svn_revnum_t base_revision;  const char *copy_path;  svn_revnum_t copy_revision;  /* Changed and removed properties */  apr_hash_t *changed_props;  apr_hash_t *removed_props;} dir_context_t;/* Represents a file to be committed. */typedef struct {  /* Pool for our file. */  apr_pool_t *pool;  /* The root commit we're in progress for. */  commit_context_t *commit;  dir_context_t *parent_dir;  const char *name;  /* The checked out context for this file. */  checkout_context_t *checkout;  /* The base revision of the file. */  svn_revnum_t base_revision;  /* Copy path and revision */  const char *copy_path;  svn_revnum_t copy_revision;  /* stream */  svn_stream_t *stream;  /* Temporary file containing the svndiff. */  apr_file_t *svndiff;  /* Our base checksum as reported by the WC. */  const char *base_checksum;  /* Our resulting checksum as reported by the WC. */  const char *result_checksum;  /* Changed and removed properties. */  apr_hash_t *changed_props;  apr_hash_t *removed_props;  /* URL to PUT the file at. */  const char *put_url;} file_context_t;/* Setup routines and handlers for various requests we'll invoke. */static svn_error_t *return_response_err(svn_ra_serf__handler_t *handler,                    svn_ra_serf__simple_request_context_t *ctx){  SVN_ERR(ctx->server_error.error);  return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,                           "%s of '%s': %d %s",                           handler->method, handler->path,                           ctx->status, ctx->reason);}#define CHECKOUT_HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?><D:checkout xmlns:D=\"DAV:\"><D:activity-set><D:href>"  #define CHECKOUT_TRAILER "</D:href></D:activity-set></D:checkout>"static serf_bucket_t *create_checkout_body(void *baton,                     serf_bucket_alloc_t *alloc,                     apr_pool_t *pool){  checkout_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(CHECKOUT_HEADER,                                          sizeof(CHECKOUT_HEADER) - 1,                                          alloc);  serf_bucket_aggregate_append(body_bkt, tmp_bkt);  tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN(ctx->activity_url,                                          ctx->activity_url_len,                                          alloc);  serf_bucket_aggregate_append(body_bkt, tmp_bkt);  tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN(CHECKOUT_TRAILER,                                          sizeof(CHECKOUT_TRAILER) - 1,                                          alloc);  serf_bucket_aggregate_append(body_bkt, tmp_bkt);  return body_bkt;}static apr_status_thandle_checkout(serf_request_t *request,                serf_bucket_t *response,                void *handler_baton,                apr_pool_t *pool){  checkout_context_t *ctx = handler_baton;  apr_status_t status;  status = svn_ra_serf__handle_status_only(request, response, &ctx->progress,                                           pool);  /* Get the resulting location. */  if (ctx->progress.done && ctx->progress.status == 201)    {      serf_bucket_t *hdrs;      apr_uri_t uri;      const char *location;      hdrs = serf_bucket_response_get_headers(response);      location = serf_bucket_headers_get(hdrs, "Location");      if (!location)        {          abort();        }      apr_uri_parse(pool, location, &uri);      ctx->resource_url = apr_pstrdup(ctx->pool, uri.path);    }  return status;}static svn_error_t *checkout_dir(dir_context_t *dir){  checkout_context_t *checkout_ctx;  svn_ra_serf__handler_t *handler;  if (dir->checkout)    {      return SVN_NO_ERROR;    }  if (dir->parent_dir)    {      /* Is our parent a copy?  If so, we're already implicitly checked out. */      if (apr_hash_get(dir->commit->copied_entries,                       dir->parent_dir->name, APR_HASH_KEY_STRING))        {          /* 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 =            svn_path_url_add_component(dir->parent_dir->checkout->resource_url,                                       svn_path_basename(dir->name, dir->pool),                                       dir->pool);                    apr_hash_set(dir->commit->copied_entries,                       apr_pstrdup(dir->commit->pool, dir->name),                       APR_HASH_KEY_STRING, (void*)1);          return SVN_NO_ERROR;        }    }  /* Checkout our directory into the activity URL now. */  handler = apr_pcalloc(dir->pool, sizeof(*handler));  handler->session = dir->commit->session;  handler->conn = dir->commit->conn;  checkout_ctx = apr_pcalloc(dir->pool, sizeof(*checkout_ctx));  checkout_ctx->pool = dir->pool;  checkout_ctx->activity_url = dir->commit->activity_url;  checkout_ctx->activity_url_len = dir->commit->activity_url_len;  /* We could be called twice for the root: once to checkout the baseline;   * once to checkout the directory itself if we need to do so.   */  if (!dir->parent_dir && !dir->commit->baseline)    {      checkout_ctx->checkout_url = dir->commit->baseline_url;      dir->commit->baseline = checkout_ctx;    }  else    {      checkout_ctx->checkout_url = dir->checked_in_url;      dir->checkout = checkout_ctx;    }  handler->body_delegate = create_checkout_body;  handler->body_delegate_baton = checkout_ctx;  handler->body_type = "text/xml";  handler->response_handler = handle_checkout;  handler->response_baton = checkout_ctx;  handler->method = "CHECKOUT";  handler->path = checkout_ctx->checkout_url;  svn_ra_serf__request_create(handler);  SVN_ERR(svn_ra_serf__context_run_wait(&checkout_ctx->progress.done,                                        dir->commit->session,                                        dir->pool));  if (checkout_ctx->progress.status != 201)    {      if (checkout_ctx->progress.status == 404)        {          return svn_error_createf(SVN_ERR_RA_DAV_PATH_NOT_FOUND,                                  return_response_err(handler,                                                      &checkout_ctx->progress),                                  _("Path '%s' not present"),                                  dir->name);        }      return svn_error_createf(SVN_ERR_RA_DAV_PATH_NOT_FOUND,                    return_response_err(handler,                                        &checkout_ctx->progress),                    _("Your file or directory '%s' is probably out-of-date"),                    svn_path_local_style(dir->name, dir->pool));    }  return SVN_NO_ERROR;}static svn_error_t *checkout_file(file_context_t *file){  svn_ra_serf__handler_t *handler;  /* Checkout our file into the activity URL now. */  handler = apr_pcalloc(file->pool, sizeof(*handler));  handler->session = file->commit->session;  handler->conn = file->commit->conn;  file->checkout = apr_pcalloc(file->pool, sizeof(*file->checkout));  file->checkout->pool = file->pool;  file->checkout->activity_url = file->commit->activity_url;  file->checkout->activity_url_len = file->commit->activity_url_len;  /* Append our file name to the baseline to get the resulting checkout. */  file->checkout->checkout_url =      svn_path_url_add_component(file->commit->checked_in_url,                                 file->name, file->pool);  handler->body_delegate = create_checkout_body;  handler->body_delegate_baton = file->checkout;  handler->body_type = "text/xml";  handler->response_handler = handle_checkout;  handler->response_baton = file->checkout;  handler->method = "CHECKOUT";  handler->path = file->checkout->checkout_url;  svn_ra_serf__request_create(handler);  /* There's no need to wait here as we only need this when we start the   * PROPPATCH or PUT of the file.   */  SVN_ERR(svn_ra_serf__context_run_wait(&file->checkout->progress.done,                                        file->commit->session,                                        file->pool));  if (file->checkout->progress.status != 201)    {      if (file->checkout->progress.status == 404)        {          return svn_error_createf(SVN_ERR_RA_DAV_PATH_NOT_FOUND,                              return_response_err(handler,                                                  &file->checkout->progress),                              _("Path '%s' not present"),                              file->name);        }      return svn_error_createf(SVN_ERR_RA_DAV_PATH_NOT_FOUND,                    return_response_err(handler,                                        &file->checkout->progress),                    _("Your file or directory '%s' is probably out-of-date"),                    svn_path_local_style(file->name, file->pool));    }  return SVN_NO_ERROR;}static svn_error_t *get_version_url(dir_context_t *dir){  svn_ra_serf__session_t *session = dir->commit->session;  const char *root_checkout;  if (dir->commit->session->wc_callbacks->get_wc_prop)    {      const svn_string_t *current_version;      SVN_ERR(session->wc_callbacks->get_wc_prop(session->wc_callback_baton,                                                 dir->name,                                                 SVN_RA_SERF__WC_CHECKED_IN_URL,                                                 &current_version, dir->pool));      if (current_version)        {          dir->checked_in_url = current_version->data;          return SVN_NO_ERROR;        }    }  if (dir->commit->checked_in_url)    {      root_checkout = dir->commit->checked_in_url;    }  else    {      svn_ra_serf__propfind_context_t *propfind_ctx;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -