Example #1
0
/* This implements the `svn_opt_subcommand_t' interface. */
svn_error_t *
svn_cl__status(apr_getopt_t *os,
               void *baton,
               apr_pool_t *pool)
{
    svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
    svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
    apr_array_header_t *targets;
    apr_pool_t *subpool;
    apr_hash_t *master_cl_hash = apr_hash_make(pool);
    int i;
    svn_opt_revision_t rev;
    struct status_baton sb;

    SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
            opt_state->targets,
            ctx, pool));

    /* Add "." if user passed 0 arguments */
    svn_opt_push_implicit_dot_target(targets, pool);

    /* We want our -u statuses to be against HEAD. */
    rev.kind = svn_opt_revision_head;

    /* The notification callback, leave the notifier as NULL in XML mode */
    if (! opt_state->xml)
        svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2, FALSE,
                             FALSE, FALSE, pool);

    subpool = svn_pool_create(pool);

    sb.had_print_error = FALSE;

    if (opt_state->xml)
    {
        /* If output is not incremental, output the XML header and wrap
           everything in a top-level element. This makes the output in
           its entirety a well-formed XML document. */
        if (! opt_state->incremental)
            SVN_ERR(svn_cl__xml_print_header("status", pool));
    }
    else
    {
        if (opt_state->incremental)
            return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                    _("'incremental' option only valid in XML "
                                      "mode"));
    }

    sb.detailed = (opt_state->verbose || opt_state->update);
    sb.show_last_committed = opt_state->verbose;
    sb.skip_unrecognized = opt_state->quiet;
    sb.repos_locks = opt_state->update;
    sb.xml_mode = opt_state->xml;
    sb.cached_changelists = master_cl_hash;
    sb.cl_pool = pool;

    SVN_ERR(svn_opt__eat_peg_revisions(&targets, targets, pool));

    for (i = 0; i < targets->nelts; i++)
    {
        const char *target = APR_ARRAY_IDX(targets, i, const char *);
        svn_revnum_t repos_rev = SVN_INVALID_REVNUM;

        svn_pool_clear(subpool);

        SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));

        if (opt_state->xml)
            SVN_ERR(print_start_target_xml(svn_path_local_style(target, subpool),
                                           subpool));

        /* Retrieve a hash of status structures with the information
           requested by the user. */
        SVN_ERR(svn_cl__try(svn_client_status4(&repos_rev, target, &rev,
                                               print_status, &sb,
                                               opt_state->depth,
                                               opt_state->verbose,
                                               opt_state->update,
                                               opt_state->no_ignore,
                                               opt_state->ignore_externals,
                                               opt_state->changelists,
                                               ctx, subpool),
                            NULL, opt_state->quiet,
                            /* not versioned: */
                            SVN_ERR_WC_NOT_DIRECTORY,
                            SVN_NO_ERROR));

        if (opt_state->xml)
            SVN_ERR(print_finish_target_xml(repos_rev, subpool));
    }

    /* If any paths were cached because they were associatied with
       changelists, we can now display them as grouped changelists. */
    if (apr_hash_count(master_cl_hash) > 0)
    {
        apr_hash_index_t *hi;
        svn_stringbuf_t *buf;

        if (opt_state->xml)
            buf = svn_stringbuf_create("", pool);

        for (hi = apr_hash_first(pool, master_cl_hash); hi;
                hi = apr_hash_next(hi))
        {
            const char *changelist_name;
            apr_array_header_t *path_array;
            const void *key;
            void *val;
            int j;

            apr_hash_this(hi, &key, NULL, &val);
            changelist_name = key;
            path_array = val;

            /* ### TODO: For non-XML output, we shouldn't print the
               ### leading \n on the first changelist if there were no
               ### non-changelist entries. */
            if (opt_state->xml)
            {
                svn_stringbuf_set(buf, "");
                svn_xml_make_open_tag(&buf, pool, svn_xml_normal, "changelist",
                                      "name", changelist_name, NULL);
                SVN_ERR(svn_cl__error_checked_fputs(buf->data, stdout));
            }
            else
                SVN_ERR(svn_cmdline_printf(pool, _("\n--- Changelist '%s':\n"),
                                           changelist_name));

            for (j = 0; j < path_array->nelts; j++)
            {
                struct status_cache *scache =
                    APR_ARRAY_IDX(path_array, j, struct status_cache *);
                SVN_ERR(print_status_normal_or_xml(&sb, scache->path,
                                                   scache->status, pool));
            }

            if (opt_state->xml)
            {
                svn_stringbuf_set(buf, "");
                svn_xml_make_close_tag(&buf, pool, "changelist");
                SVN_ERR(svn_cl__error_checked_fputs(buf->data, stdout));
            }
        }
    }
Example #2
0
/* This implements the `svn_opt_subcommand_t' interface. */
svn_error_t *
svn_cl__status(apr_getopt_t *os,
               void *baton,
               apr_pool_t *scratch_pool)
{
  svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
  svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
  apr_array_header_t *targets;
  apr_pool_t *iterpool;
  apr_hash_t *master_cl_hash = apr_hash_make(scratch_pool);
  int i;
  svn_opt_revision_t rev;
  struct status_baton sb;

  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                      opt_state->targets,
                                                      ctx, FALSE,
                                                      scratch_pool));

  /* Add "." if user passed 0 arguments */
  svn_opt_push_implicit_dot_target(targets, scratch_pool);

  SVN_ERR(svn_cl__check_targets_are_local_paths(targets));

  /* We want our -u statuses to be against HEAD by default. */
  if (opt_state->start_revision.kind == svn_opt_revision_unspecified)
    rev.kind = svn_opt_revision_head;
  else if (! opt_state->update)
    return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                        _("--revision (-r) option valid only with "
                          "--show-updates (-u) option"));
  else
    rev = opt_state->start_revision;

  sb.had_print_error = FALSE;

  if (opt_state->xml)
    {
      /* If output is not incremental, output the XML header and wrap
         everything in a top-level element. This makes the output in
         its entirety a well-formed XML document. */
      if (! opt_state->incremental)
        SVN_ERR(svn_cl__xml_print_header("status", scratch_pool));
    }
  else
    {
      if (opt_state->incremental)
        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                _("'incremental' option only valid in XML "
                                  "mode"));
    }

  sb.suppress_externals_placeholders = (opt_state->quiet
                                        && (! opt_state->verbose));
  sb.detailed = (opt_state->verbose || opt_state->update);
  sb.show_last_committed = opt_state->verbose;
  sb.skip_unrecognized = opt_state->quiet;
  sb.repos_locks = opt_state->update;
  sb.xml_mode = opt_state->xml;
  sb.cached_changelists = master_cl_hash;
  sb.cl_pool = scratch_pool;
  sb.text_conflicts = 0;
  sb.prop_conflicts = 0;
  sb.tree_conflicts = 0;
  sb.ctx = ctx;

  SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, scratch_pool));

  iterpool = svn_pool_create(scratch_pool);
  for (i = 0; i < targets->nelts; i++)
    {
      const char *target = APR_ARRAY_IDX(targets, i, const char *);
      svn_revnum_t repos_rev = SVN_INVALID_REVNUM;

      svn_pool_clear(iterpool);

      SVN_ERR(svn_dirent_get_absolute(&(sb.target_abspath), target,
                                      scratch_pool));
      sb.target_path = target;

      SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));

      if (opt_state->xml)
        SVN_ERR(print_start_target_xml(svn_dirent_local_style(target, iterpool),
                                       iterpool));

      /* Retrieve a hash of status structures with the information
         requested by the user. */
      SVN_ERR(svn_cl__try(svn_client_status6(&repos_rev, ctx, target, &rev,
                                             opt_state->depth,
                                             opt_state->verbose,
                                             opt_state->update,
                                             TRUE /* check_working_copy */,
                                             opt_state->no_ignore,
                                             opt_state->ignore_externals,
                                             FALSE /* depth_as_sticky */,
                                             opt_state->changelists,
                                             print_status, &sb,
                                             iterpool),
                          NULL, opt_state->quiet,
                          /* not versioned: */
                          SVN_ERR_WC_NOT_WORKING_COPY,
                          SVN_ERR_WC_PATH_NOT_FOUND,
                          0));

      if (opt_state->xml)
        SVN_ERR(print_finish_target_xml(repos_rev, iterpool));
    }

  /* If any paths were cached because they were associated with
     changelists, we can now display them as grouped changelists. */
  if (apr_hash_count(master_cl_hash) > 0)
    {
      apr_hash_index_t *hi;
      svn_stringbuf_t *buf;

      if (opt_state->xml)
        buf = svn_stringbuf_create_empty(scratch_pool);

      for (hi = apr_hash_first(scratch_pool, master_cl_hash); hi;
           hi = apr_hash_next(hi))
        {
          const char *changelist_name = apr_hash_this_key(hi);
          apr_array_header_t *path_array = apr_hash_this_val(hi);
          int j;

          /* ### TODO: For non-XML output, we shouldn't print the
             ### leading \n on the first changelist if there were no
             ### non-changelist entries. */
          if (opt_state->xml)
            {
              svn_stringbuf_setempty(buf);
              svn_xml_make_open_tag(&buf, scratch_pool, svn_xml_normal,
                                    "changelist", "name", changelist_name,
                                    SVN_VA_NULL);
              SVN_ERR(svn_cl__error_checked_fputs(buf->data, stdout));
            }
          else
            SVN_ERR(svn_cmdline_printf(scratch_pool,
                                       _("\n--- Changelist '%s':\n"),
                                       changelist_name));

          for (j = 0; j < path_array->nelts; j++)
            {
              struct status_cache *scache =
                APR_ARRAY_IDX(path_array, j, struct status_cache *);
              sb.target_abspath = scache->target_abspath;
              sb.target_path = scache->target_path;
              SVN_ERR(print_status_normal_or_xml(&sb, scache->path,
                                                 scache->status, scratch_pool));
            }

          if (opt_state->xml)
            {
              svn_stringbuf_setempty(buf);
              svn_xml_make_close_tag(&buf, scratch_pool, "changelist");
              SVN_ERR(svn_cl__error_checked_fputs(buf->data, stdout));
            }
        }
    }