예제 #1
0
파일: commit.c 프로젝트: 2asoft/freebsd
static svn_error_t *
invoke_commit_cb(svn_commit_callback2_t commit_cb,
                 void *commit_baton,
                 svn_fs_t *fs,
                 svn_revnum_t revision,
                 const char *post_commit_errstr,
                 apr_pool_t *scratch_pool)
{
  /* FS interface returns non-const values.  */
  /* const */ svn_string_t *date;
  /* const */ svn_string_t *author;
  svn_commit_info_t *commit_info;

  if (commit_cb == NULL)
    return SVN_NO_ERROR;

  SVN_ERR(svn_fs_revision_prop(&date, fs, revision, SVN_PROP_REVISION_DATE,
                               scratch_pool));
  SVN_ERR(svn_fs_revision_prop(&author, fs, revision,
                               SVN_PROP_REVISION_AUTHOR,
                               scratch_pool));

  commit_info = svn_create_commit_info(scratch_pool);

  /* fill up the svn_commit_info structure */
  commit_info->revision = revision;
  commit_info->date = date ? date->data : NULL;
  commit_info->author = author ? author->data : NULL;
  commit_info->post_commit_err = post_commit_errstr;
  /* commit_info->repos_root is not set by the repos layer, only by RA layers */

  return svn_error_trace(commit_cb(commit_info, commit_baton, scratch_pool));
}
예제 #2
0
svn_error_t *
svn_ra_serf__run_merge(const svn_commit_info_t **commit_info,
                       svn_ra_serf__session_t *session,
                       const char *merge_resource_url,
                       apr_hash_t *lock_tokens,
                       svn_boolean_t keep_locks,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
{
  merge_context_t *merge_ctx;
  svn_ra_serf__handler_t *handler;
  svn_ra_serf__xml_context_t *xmlctx;

  merge_ctx = apr_pcalloc(scratch_pool, sizeof(*merge_ctx));

  merge_ctx->pool = result_pool;
  merge_ctx->session = session;

  merge_ctx->merge_resource_url = merge_resource_url;

  merge_ctx->lock_tokens = lock_tokens;
  merge_ctx->keep_locks = keep_locks;

  /* We don't need the full merge response when working over HTTPv2.
   * Over HTTPv1, this response is only required with a non-null
   * svn_ra_push_wc_prop_func_t callback. */
  merge_ctx->disable_merge_response =
    SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session) ||
    session->wc_callbacks->push_wc_prop == NULL;

  merge_ctx->commit_info = svn_create_commit_info(result_pool);

  merge_ctx->merge_url = session->session_url.path;

  xmlctx = svn_ra_serf__xml_context_create(merge_ttable,
                                           NULL, merge_closed, NULL,
                                           merge_ctx,
                                           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->body_type = "text/xml";

  handler->header_delegate = setup_merge_headers;
  handler->header_delegate_baton = merge_ctx;

  merge_ctx->handler = handler;

  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;

  /* 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;
}
예제 #3
0
파일: commit.c 프로젝트: DJEX93/dsploit
static svn_error_t *
close_edit(void *edit_baton,
           apr_pool_t *pool)
{
  struct edit_baton *eb = edit_baton;
  svn_revnum_t new_revision = SVN_INVALID_REVNUM;
  svn_error_t *err;
  const char *conflict;
  const char *post_commit_err = NULL;

  /* If no transaction has been created (ie. if open_root wasn't
     called before close_edit), abort the operation here with an
     error. */
  if (! eb->txn)
    return svn_error_create(SVN_ERR_REPOS_BAD_ARGS, NULL,
                            "No valid transaction supplied to close_edit");

  /* Commit. */
  err = svn_repos_fs_commit_txn(&conflict, eb->repos,
                                &new_revision, eb->txn, pool);

  if (SVN_IS_VALID_REVNUM(new_revision))
    {
      if (err)
        {
          /* If the error was in post-commit, then the commit itself
             succeeded.  In which case, save the post-commit warning
             (to be reported back to the client, who will probably
             display it as a warning) and clear the error. */
          post_commit_err = svn_repos__post_commit_error_str(err, pool);
          svn_error_clear(err);
          err = SVN_NO_ERROR;
        }
    }
  else
    {
      /* ### todo: we should check whether it really was a conflict,
         and return the conflict info if so? */

      /* If the commit failed, it's *probably* due to a conflict --
         that is, the txn being out-of-date.  The filesystem gives us
         the ability to continue diddling the transaction and try
         again; but let's face it: that's not how the cvs or svn works
         from a user interface standpoint.  Thus we don't make use of
         this fs feature (for now, at least.)

         So, in a nutshell: svn commits are an all-or-nothing deal.
         Each commit creates a new fs txn which either succeeds or is
         aborted completely.  No second chances;  the user simply
         needs to update and commit again  :) */

      eb->txn_aborted = TRUE;

      return svn_error_trace(
                svn_error_compose_create(err,
                                         svn_fs_abort_txn(eb->txn, pool)));
    }

  /* Pass new revision information to the caller's callback. */
  {
    svn_string_t *date, *author;
    svn_commit_info_t *commit_info;

    /* Even if there was a post-commit hook failure, it's more serious
       if one of the calls here fails, so we explicitly check for errors
       here, while saving the possible post-commit error for later. */

    err = svn_fs_revision_prop(&date, svn_repos_fs(eb->repos),
                                new_revision, SVN_PROP_REVISION_DATE,
                                pool);
    if (! err)
      {
        err = svn_fs_revision_prop(&author, svn_repos_fs(eb->repos),
                                   new_revision, SVN_PROP_REVISION_AUTHOR,
                                   pool);
      }

    if ((! err) && eb->commit_callback)
      {
        commit_info = svn_create_commit_info(pool);

        /* fill up the svn_commit_info structure */
        commit_info->revision = new_revision;
        commit_info->date = date ? date->data : NULL;
        commit_info->author = author ? author->data : NULL;
        commit_info->post_commit_err = post_commit_err;
        err = (*eb->commit_callback)(commit_info,
                                     eb->commit_callback_baton,
                                     pool);
      }
  }

  return svn_error_trace(err);
}
예제 #4
0
파일: merge.c 프로젝트: JasonFord53/freebsd
svn_error_t *
svn_ra_serf__run_merge(const svn_commit_info_t **commit_info,
                       svn_ra_serf__session_t *session,
                       const char *merge_resource_url,
                       apr_hash_t *lock_tokens,
                       svn_boolean_t keep_locks,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
{
  merge_context_t *merge_ctx;
  svn_ra_serf__handler_t *handler;
  svn_ra_serf__xml_context_t *xmlctx;

  merge_ctx = apr_pcalloc(scratch_pool, sizeof(*merge_ctx));

  merge_ctx->pool = result_pool;
  merge_ctx->session = session;

  merge_ctx->merge_resource_url = merge_resource_url;

  merge_ctx->lock_tokens = lock_tokens;
  merge_ctx->keep_locks = keep_locks;

  merge_ctx->commit_info = svn_create_commit_info(result_pool);

  merge_ctx->merge_url = session->session_url.path;

  xmlctx = svn_ra_serf__xml_context_create(merge_ttable,
                                           NULL, merge_closed, NULL,
                                           merge_ctx,
                                           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->header_delegate = setup_merge_headers;
  handler->header_delegate_baton = merge_ctx;

  merge_ctx->handler = handler;

  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;

  /* 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;
}