Ejemplo n.º 1
0
static svn_error_t *
bench_null_export(svn_revnum_t *result_rev,
                  const char *from_path_or_url,
                  svn_opt_revision_t *peg_revision,
                  svn_opt_revision_t *revision,
                  svn_depth_t depth,
                  void *baton,
                  svn_client_ctx_t *ctx,
                  svn_boolean_t quiet,
                  apr_pool_t *pool)
{
    svn_revnum_t edit_revision = SVN_INVALID_REVNUM;
    svn_boolean_t from_is_url = svn_path_is_url(from_path_or_url);

    SVN_ERR_ASSERT(peg_revision != NULL);
    SVN_ERR_ASSERT(revision != NULL);

    if (peg_revision->kind == svn_opt_revision_unspecified)
        peg_revision->kind = svn_path_is_url(from_path_or_url)
                             ? svn_opt_revision_head
                             : svn_opt_revision_working;

    if (revision->kind == svn_opt_revision_unspecified)
        revision = peg_revision;

    if (from_is_url || ! SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(revision->kind))
    {
        svn_client__pathrev_t *loc;
        svn_ra_session_t *ra_session;
        svn_node_kind_t kind;

        /* Get the RA connection. */
        SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &loc,
                from_path_or_url, NULL,
                peg_revision,
                revision, ctx, pool));

        SVN_ERR(svn_ra_check_path(ra_session, "", loc->rev, &kind, pool));

        if (kind == svn_node_file)
        {
            apr_hash_t *props;

            /* Since you cannot actually root an editor at a file, we
             * manually drive a few functions of our editor. */

            /* Step outside the editor-likeness for a moment, to actually talk
             * to the repository. */
            /* ### note: the stream will not be closed */
            SVN_ERR(svn_ra_get_file(ra_session, "", loc->rev,
                                    svn_stream_empty(pool),
                                    NULL, &props, pool));
        }
        else if (kind == svn_node_dir)
        {
            void *edit_baton = NULL;
            const svn_delta_editor_t *export_editor = NULL;
            const svn_ra_reporter3_t *reporter;
            void *report_baton;

            svn_delta_editor_t *editor = svn_delta_default_editor(pool);

            editor->set_target_revision = set_target_revision;
            editor->open_root = open_root;
            editor->add_directory = add_directory;
            editor->add_file = add_file;
            editor->apply_textdelta = apply_textdelta;
            editor->close_file = close_file;
            editor->change_file_prop = change_file_prop;
            editor->change_dir_prop = change_dir_prop;

            /* for ra_svn, we don't need an editior in quiet mode */
            if (!quiet || strncmp(loc->repos_root_url, "svn:", 4))
                SVN_ERR(svn_delta_get_cancellation_editor(ctx->cancel_func,
                        ctx->cancel_baton,
                        editor,
                        baton,
                        &export_editor,
                        &edit_baton,
                        pool));

            /* Manufacture a basic 'report' to the update reporter. */
            SVN_ERR(svn_ra_do_update3(ra_session,
                                      &reporter, &report_baton,
                                      loc->rev,
                                      "", /* no sub-target */
                                      depth,
                                      FALSE, /* don't want copyfrom-args */
                                      FALSE, /* don't want ignore_ancestry */
                                      export_editor, edit_baton,
                                      pool, pool));

            SVN_ERR(reporter->set_path(report_baton, "", loc->rev,
                                       /* Depth is irrelevant, as we're
                                          passing start_empty=TRUE anyway. */
                                       svn_depth_infinity,
                                       TRUE, /* "help, my dir is empty!" */
                                       NULL, pool));

            SVN_ERR(reporter->finish_report(report_baton, pool));
        }
        else if (kind == svn_node_none)
        {
            return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
                                     _("URL '%s' doesn't exist"),
                                     from_path_or_url);
        }
        /* kind == svn_node_unknown not handled */
    }


    if (result_rev)
        *result_rev = edit_revision;

    return SVN_NO_ERROR;
}
Ejemplo n.º 2
0
/* Note: this implementation is very similar to svn_client_proplist. */
svn_error_t *
svn_client_propget4(apr_hash_t **props,
                    const char *propname,
                    const char *target,
                    const svn_opt_revision_t *peg_revision,
                    const svn_opt_revision_t *revision,
                    svn_revnum_t *actual_revnum,
                    svn_depth_t depth,
                    const apr_array_header_t *changelists,
                    svn_client_ctx_t *ctx,
                    apr_pool_t *result_pool,
                    apr_pool_t *scratch_pool)
{
  svn_revnum_t revnum;

  SVN_ERR(error_if_wcprop_name(propname));
  if (!svn_path_is_url(target))
    SVN_ERR_ASSERT(svn_dirent_is_absolute(target));

  peg_revision = svn_cl__rev_default_to_head_or_working(peg_revision,
                                                        target);
  revision = svn_cl__rev_default_to_peg(revision, peg_revision);

  *props = apr_hash_make(result_pool);

  if (! svn_path_is_url(target)
      && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(peg_revision->kind)
      && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(revision->kind))
    {
      svn_node_kind_t kind;
      svn_boolean_t pristine;
      svn_error_t *err;

      /* If FALSE, we want the working revision. */
      pristine = (revision->kind == svn_opt_revision_committed
                  || revision->kind == svn_opt_revision_base);

      SVN_ERR(svn_wc_read_kind(&kind, ctx->wc_ctx, target, FALSE,
                               scratch_pool));

      if (kind == svn_node_unknown || kind == svn_node_none)
        {
          /* svn uses SVN_ERR_UNVERSIONED_RESOURCE as warning only
             for this function. */
          return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL,
                                   _("'%s' is not under version control"),
                                   svn_dirent_local_style(target,
                                                          scratch_pool));
        }

      err = svn_client__get_revision_number(&revnum, NULL, ctx->wc_ctx,
                                            target, NULL, revision,
                                            scratch_pool);
      if (err && err->apr_err == SVN_ERR_CLIENT_BAD_REVISION)
        {
          svn_error_clear(err);
          revnum = SVN_INVALID_REVNUM;
        }
      else if (err)
        return svn_error_trace(err);

      SVN_ERR(get_prop_from_wc(*props, propname, target,
                               pristine, kind,
                               depth, changelists, ctx, scratch_pool,
                               result_pool));
    }
  else
    {
      const char *url;
      svn_ra_session_t *ra_session;
      svn_node_kind_t kind;

      /* Get an RA plugin for this filesystem object. */
      SVN_ERR(svn_client__ra_session_from_path(&ra_session, &revnum,
                                               &url, target, NULL,
                                               peg_revision,
                                               revision, ctx, scratch_pool));

      SVN_ERR(svn_ra_check_path(ra_session, "", revnum, &kind, scratch_pool));

      SVN_ERR(remote_propget(*props, propname, url, "",
                             kind, revnum, ra_session,
                             depth, result_pool, scratch_pool));
    }

  if (actual_revnum)
    *actual_revnum = revnum;
  return SVN_NO_ERROR;
}
Ejemplo n.º 3
0
svn_error_t *
svn_client__get_normalized_stream(svn_stream_t **normal_stream,
                                  svn_wc_context_t *wc_ctx,
                                  const char *local_abspath,
                                  const svn_opt_revision_t *revision,
                                  svn_boolean_t expand_keywords,
                                  svn_boolean_t normalize_eols,
                                  svn_cancel_func_t cancel_func,
                                  void *cancel_baton,
                                  apr_pool_t *result_pool,
                                  apr_pool_t *scratch_pool)
{
  apr_hash_t *kw = NULL;
  svn_subst_eol_style_t style;
  apr_hash_t *props;
  svn_string_t *eol_style, *keywords, *special;
  const char *eol = NULL;
  svn_boolean_t local_mod = FALSE;
  apr_time_t tm;
  svn_stream_t *input;
  svn_node_kind_t kind;

  SVN_ERR_ASSERT(SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(revision->kind));

  SVN_ERR(svn_wc_read_kind(&kind, wc_ctx, local_abspath, FALSE, scratch_pool));

  if (kind == svn_node_unknown || kind == svn_node_none)
    return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL,
                             _("'%s' is not under version control"),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool));
  if (kind != svn_node_file)
    return svn_error_createf(SVN_ERR_CLIENT_IS_DIRECTORY, NULL,
                             _("'%s' refers to a directory"),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool));

  if (revision->kind != svn_opt_revision_working)
    {
      SVN_ERR(svn_wc_get_pristine_contents2(&input, wc_ctx, local_abspath,
                                            result_pool, scratch_pool));
      if (input == NULL)
        return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
                 _("'%s' has no base revision until it is committed"),
                 svn_dirent_local_style(local_abspath, scratch_pool));

      SVN_ERR(svn_wc_get_pristine_props(&props, wc_ctx, local_abspath,
                                        scratch_pool, scratch_pool));
    }
  else
    {
      svn_wc_status3_t *status;

      SVN_ERR(svn_stream_open_readonly(&input, local_abspath, scratch_pool,
                                       result_pool));

      SVN_ERR(svn_wc_prop_list2(&props, wc_ctx, local_abspath, scratch_pool,
                                scratch_pool));
      SVN_ERR(svn_wc_status3(&status, wc_ctx, local_abspath, scratch_pool,
                             scratch_pool));
      if (status->text_status != svn_wc_status_normal)
        local_mod = TRUE;
    }

  eol_style = apr_hash_get(props, SVN_PROP_EOL_STYLE,
                           APR_HASH_KEY_STRING);
  keywords = apr_hash_get(props, SVN_PROP_KEYWORDS,
                          APR_HASH_KEY_STRING);
  special = apr_hash_get(props, SVN_PROP_SPECIAL,
                         APR_HASH_KEY_STRING);

  if (eol_style)
    svn_subst_eol_style_from_value(&style, &eol, eol_style->data);

  if (local_mod && (! special))
    {
      /* Use the modified time from the working copy if
         the file */
      SVN_ERR(svn_io_file_affected_time(&tm, local_abspath, scratch_pool));
    }
  else
    {
      SVN_ERR(svn_wc__node_get_changed_info(NULL, &tm, NULL, wc_ctx,
                                            local_abspath, scratch_pool,
                                            scratch_pool));
    }

  if (keywords)
    {
      svn_revnum_t changed_rev;
      const char *rev_str;
      const char *author;
      const char *url;

      SVN_ERR(svn_wc__node_get_changed_info(&changed_rev, NULL, &author, wc_ctx,
                                            local_abspath, scratch_pool,
                                            scratch_pool));
      SVN_ERR(svn_wc__node_get_url(&url, wc_ctx, local_abspath, scratch_pool,
                                   scratch_pool));

      if (local_mod)
        {
          /* For locally modified files, we'll append an 'M'
             to the revision number, and set the author to
             "(local)" since we can't always determine the
             current user's username */
          rev_str = apr_psprintf(scratch_pool, "%ldM", changed_rev);
          author = _("(local)");
        }
      else
        {
          rev_str = apr_psprintf(scratch_pool, "%ld", changed_rev);
        }

      SVN_ERR(svn_subst_build_keywords2(&kw, keywords->data, rev_str, url, tm,
                                        author, scratch_pool));
    }

  /* Wrap the output stream if translation is needed. */
  if (eol != NULL || kw != NULL)
    input = svn_subst_stream_translated(
      input,
      (eol_style && normalize_eols) ? SVN_SUBST_NATIVE_EOL_STR : eol,
      FALSE, kw, expand_keywords, result_pool);

  *normal_stream = input;

  return SVN_NO_ERROR;
}
Ejemplo n.º 4
0
svn_error_t *
svn_client_proplist3(const char *path_or_url,
                     const svn_opt_revision_t *peg_revision,
                     const svn_opt_revision_t *revision,
                     svn_depth_t depth,
                     const apr_array_header_t *changelists,
                     svn_proplist_receiver_t receiver,
                     void *receiver_baton,
                     svn_client_ctx_t *ctx,
                     apr_pool_t *pool)
{
  const char *url;

  peg_revision = svn_cl__rev_default_to_head_or_working(peg_revision,
                                                        path_or_url);
  revision = svn_cl__rev_default_to_peg(revision, peg_revision);

  if (depth == svn_depth_unknown)
    depth = svn_depth_empty;

  if (! svn_path_is_url(path_or_url)
      && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(peg_revision->kind)
      && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(revision->kind))
    {
      svn_boolean_t pristine;
      svn_node_kind_t kind;
      apr_hash_t *changelist_hash = NULL;
      const char *local_abspath;

      SVN_ERR(svn_dirent_get_absolute(&local_abspath, path_or_url, pool));

      pristine = ((revision->kind == svn_opt_revision_committed)
                  || (revision->kind == svn_opt_revision_base));

      SVN_ERR(svn_wc_read_kind(&kind, ctx->wc_ctx, local_abspath, FALSE,
                               pool));

      if (kind == svn_node_unknown || kind == svn_node_none)
        {
          /* svn uses SVN_ERR_UNVERSIONED_RESOURCE as warning only
             for this function. */
          return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL,
                                   _("'%s' is not under version control"),
                                   svn_dirent_local_style(local_abspath,
                                                          pool));
        }

      if (changelists && changelists->nelts)
        SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash,
                                           changelists, pool));

      /* Fetch, recursively or not. */
      if (kind == svn_node_dir)
        {
          struct recursive_proplist_receiver_baton rb;

          rb.wc_ctx = ctx->wc_ctx;
          rb.wrapped_receiver = receiver;
          rb.wrapped_receiver_baton = receiver_baton;

          if (strcmp(path_or_url, local_abspath) != 0)
            {
              rb.anchor = path_or_url;
              rb.anchor_abspath = local_abspath;
            }
          else
            {
              rb.anchor = NULL;
              rb.anchor_abspath = NULL;
            }

          SVN_ERR(svn_wc__prop_list_recursive(ctx->wc_ctx, local_abspath, NULL,
                                              depth,
                                              FALSE, pristine, changelists,
                                              recursive_proplist_receiver, &rb,
                                              ctx->cancel_func,
                                              ctx->cancel_baton, pool));
        }
      else if (svn_wc__changelist_match(ctx->wc_ctx, local_abspath,
                                        changelist_hash, pool))
        {
          apr_hash_t *hash;

          SVN_ERR(pristine_or_working_props(&hash, ctx->wc_ctx, local_abspath,
                                            pristine, pool, pool));
          SVN_ERR(call_receiver(path_or_url, hash,
                                receiver, receiver_baton, pool));

        }
    }
  else /* remote target */
    {
      svn_ra_session_t *ra_session;
      svn_node_kind_t kind;
      apr_pool_t *subpool = svn_pool_create(pool);
      svn_revnum_t revnum;

      /* Get an RA session for this URL. */
      SVN_ERR(svn_client__ra_session_from_path(&ra_session, &revnum,
                                               &url, path_or_url, NULL,
                                               peg_revision,
                                               revision, ctx, pool));

      SVN_ERR(svn_ra_check_path(ra_session, "", revnum, &kind, pool));

      SVN_ERR(remote_proplist(url, "", kind, revnum, ra_session, depth,
                              receiver, receiver_baton, pool, subpool));
      svn_pool_destroy(subpool);
    }

  return SVN_NO_ERROR;
}
Ejemplo n.º 5
0
svn_error_t *
svn_client_cat2(svn_stream_t *out,
                const char *path_or_url,
                const svn_opt_revision_t *peg_revision,
                const svn_opt_revision_t *revision,
                svn_client_ctx_t *ctx,
                apr_pool_t *pool)
{
  svn_ra_session_t *ra_session;
  svn_revnum_t rev;
  svn_string_t *eol_style;
  svn_string_t *keywords;
  apr_hash_t *props;
  const char *url;
  svn_stream_t *output = out;
  svn_error_t *err;

  /* ### Inconsistent default revision logic in this command. */
  if (peg_revision->kind == svn_opt_revision_unspecified)
    {
      peg_revision = svn_cl__rev_default_to_head_or_working(peg_revision,
                                                            path_or_url);
      revision = svn_cl__rev_default_to_head_or_base(revision, path_or_url);
    }
  else
    {
      peg_revision = svn_cl__rev_default_to_head_or_working(peg_revision,
                                                            path_or_url);
      revision = svn_cl__rev_default_to_peg(revision, peg_revision);
    }

  if (! svn_path_is_url(path_or_url)
      && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(peg_revision->kind)
      && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(revision->kind))
    {
      const char *local_abspath;
      svn_stream_t *normal_stream;

      SVN_ERR(svn_dirent_get_absolute(&local_abspath, path_or_url, pool));
      SVN_ERR(svn_client__get_normalized_stream(&normal_stream, ctx->wc_ctx,
                                            local_abspath, revision, TRUE, FALSE,
                                            ctx->cancel_func, ctx->cancel_baton,
                                            pool, pool));

      /* We don't promise to close output, so disown it to ensure we don't. */
      output = svn_stream_disown(output, pool);

      return svn_error_trace(svn_stream_copy3(normal_stream, output,
                                              ctx->cancel_func,
                                              ctx->cancel_baton, pool));
    }

  /* Get an RA plugin for this filesystem object. */
  SVN_ERR(svn_client__ra_session_from_path(&ra_session, &rev,
                                           &url, path_or_url, NULL,
                                           peg_revision,
                                           revision, ctx, pool));

  /* Grab some properties we need to know in order to figure out if anything
     special needs to be done with this file. */
  err = svn_ra_get_file(ra_session, "", rev, NULL, NULL, &props, pool);
  if (err)
    {
      if (err->apr_err == SVN_ERR_FS_NOT_FILE)
        {
          return svn_error_createf(SVN_ERR_CLIENT_IS_DIRECTORY, err,
                                   _("URL '%s' refers to a directory"), url);
        }
      else
        {
          return svn_error_trace(err);
        }
    }

  eol_style = apr_hash_get(props, SVN_PROP_EOL_STYLE, APR_HASH_KEY_STRING);
  keywords = apr_hash_get(props, SVN_PROP_KEYWORDS, APR_HASH_KEY_STRING);

  if (eol_style || keywords)
    {
      /* It's a file with no special eol style or keywords. */
      svn_subst_eol_style_t eol;
      const char *eol_str;
      apr_hash_t *kw;

      if (eol_style)
        svn_subst_eol_style_from_value(&eol, &eol_str, eol_style->data);
      else
        {
          eol = svn_subst_eol_style_none;
          eol_str = NULL;
        }


      if (keywords)
        {
          svn_string_t *cmt_rev, *cmt_date, *cmt_author;
          apr_time_t when = 0;

          cmt_rev = apr_hash_get(props, SVN_PROP_ENTRY_COMMITTED_REV,
                                 APR_HASH_KEY_STRING);
          cmt_date = apr_hash_get(props, SVN_PROP_ENTRY_COMMITTED_DATE,
                                  APR_HASH_KEY_STRING);
          cmt_author = apr_hash_get(props, SVN_PROP_ENTRY_LAST_AUTHOR,
                                    APR_HASH_KEY_STRING);
          if (cmt_date)
            SVN_ERR(svn_time_from_cstring(&when, cmt_date->data, pool));

          SVN_ERR(svn_subst_build_keywords2
                  (&kw, keywords->data,
                   cmt_rev->data,
                   url,
                   when,
                   cmt_author ? cmt_author->data : NULL,
                   pool));
        }
      else
        kw = NULL;

      /* Interject a translating stream */
      output = svn_subst_stream_translated(svn_stream_disown(out, pool),
                                           eol_str, FALSE, kw, TRUE, pool);
    }

  SVN_ERR(svn_ra_get_file(ra_session, "", rev, output, NULL, NULL, pool));

  if (out != output)
    /* Close the interjected stream */
    SVN_ERR(svn_stream_close(output));

  return SVN_NO_ERROR;
}