Ejemplo n.º 1
0
/* An svn_wc_entry_callbacks2_t callback function.
   Handle an error encountered by the walker.
   If the error is "unversioned resource" and, upon checking the
   parent dir's tree conflict data, we find that PATH is a tree
   conflict victim, cancel the error and send a minimal info struct.
   Otherwise re-raise the error.
*/
static svn_error_t *
info_error_handler(const char *path,
                   svn_error_t *err,
                   void *walk_baton,
                   apr_pool_t *pool)
{
    if (err && (err->apr_err == SVN_ERR_UNVERSIONED_RESOURCE))
    {
        struct found_entry_baton *fe_baton = walk_baton;
        svn_wc_adm_access_t *adm_access;
        svn_wc_conflict_description_t *tree_conflict;

        SVN_ERR(svn_wc_adm_probe_try3(&adm_access, fe_baton->adm_access,
                                      svn_path_dirname(path, pool),
                                      FALSE, 0, NULL, NULL, pool));
        SVN_ERR(svn_wc__get_tree_conflict(&tree_conflict, path, adm_access,
                                          pool));

        if (tree_conflict)
        {
            svn_info_t *info;

            svn_error_clear(err);

            SVN_ERR(build_info_for_unversioned(&info, pool));
            info->tree_conflict = tree_conflict;

            SVN_ERR(fe_baton->receiver(fe_baton->receiver_baton, path, info,
                                       pool));
            return SVN_NO_ERROR;
        }
    }

    return err;
}
Ejemplo n.º 2
0
/* An svn_wc_entry_callbacks2_t callback function. */
static svn_error_t *
info_found_entry_callback(const char *path,
                          const svn_wc_entry_t *entry,
                          void *walk_baton,
                          apr_pool_t *pool)
{
    struct found_entry_baton *fe_baton = walk_baton;

    /* We're going to receive dirents twice;  we want to ignore the
       first one (where it's a child of a parent dir), and only print
       the second one (where we're looking at THIS_DIR.)  */
    if ((entry->kind == svn_node_dir)
            && (strcmp(entry->name, SVN_WC_ENTRY_THIS_DIR)))
        return SVN_NO_ERROR;

    if (SVN_WC__CL_MATCH(fe_baton->changelist_hash, entry))
    {
        svn_info_t *info;
        svn_wc_adm_access_t *adm_access;

        SVN_ERR(build_info_from_entry(&info, entry, path, pool));
        SVN_ERR(svn_wc_adm_probe_try3(&adm_access, fe_baton->adm_access, path,
                                      FALSE /* read-only */, 0 /* levels */,
                                      NULL, NULL, pool));
        SVN_ERR(svn_wc__get_tree_conflict(&info->tree_conflict, path, adm_access,
                                          pool));
        SVN_ERR(fe_baton->receiver(fe_baton->receiver_baton, path, info, pool));
    }
    return SVN_NO_ERROR;
}
Ejemplo n.º 3
0
/* Print STATUS and PATH in a format determined by DETAILED and
   SHOW_LAST_COMMITTED. */
static svn_error_t *
print_status(const char *cwd_abspath, const char *path,
             svn_boolean_t detailed,
             svn_boolean_t show_last_committed,
             svn_boolean_t repos_locks,
             const svn_client_status_t *status,
             unsigned int *text_conflicts,
             unsigned int *prop_conflicts,
             unsigned int *tree_conflicts,
             svn_client_ctx_t *ctx,
             apr_pool_t *pool)
{
  enum svn_wc_status_kind node_status = status->node_status;
  enum svn_wc_status_kind prop_status = status->prop_status;
  char tree_status_code = ' ';
  const char *tree_desc_line = "";
  const char *moved_from_line = "";
  const char *moved_to_line = "";

  path = make_relpath(cwd_abspath, path, pool, pool);

  /* For historic reasons svn ignores the property status for added nodes, even
     if these nodes were copied and have local property changes.

     Note that it doesn't do this on replacements, or children of copies.

     ### Our test suite would catch more errors if we reported property
         changes on copies. */
  if (node_status == svn_wc_status_added)
      prop_status = svn_wc_status_none;

  /* To indicate this node is the victim of a tree conflict, we show
     'C' in the tree-conflict column, overriding any other status.
     We also print a separate line describing the nature of the tree
     conflict. */
  if (status->conflicted)
    {
      const char *desc;
      const char *local_abspath = status->local_abspath;
      svn_boolean_t text_conflicted;
      svn_boolean_t prop_conflicted;
      svn_boolean_t tree_conflicted;

      if (status->versioned)
        {
          svn_error_t *err;

          err = svn_wc_conflicted_p3(&text_conflicted,
                                     &prop_conflicted,
                                     &tree_conflicted, ctx->wc_ctx,
                                     local_abspath, pool);

          if (err && err->apr_err == SVN_ERR_WC_UPGRADE_REQUIRED)
            {
              svn_error_clear(err);
              text_conflicted = FALSE;
              prop_conflicted = FALSE;
              tree_conflicted = FALSE;
            }
          else
            SVN_ERR(err);
        }
      else
        {
          text_conflicted = FALSE;
          prop_conflicted = FALSE;
          tree_conflicted = TRUE;
        }

      if (tree_conflicted)
        {
          const svn_wc_conflict_description2_t *tree_conflict;
          SVN_ERR(svn_wc__get_tree_conflict(&tree_conflict, ctx->wc_ctx,
                                            local_abspath, pool, pool));
          SVN_ERR_ASSERT(tree_conflict != NULL);

          tree_status_code = 'C';
          SVN_ERR(svn_cl__get_human_readable_tree_conflict_description(
                            &desc, tree_conflict, pool));
          tree_desc_line = apr_psprintf(pool, "\n      >   %s", desc);
          (*tree_conflicts)++;
        }
      else if (text_conflicted)
        (*text_conflicts)++;
      else if (prop_conflicted)
        (*prop_conflicts)++;
    }

  /* Note that moved-from and moved-to information is only available in STATUS
   * for (op-)roots of a move. Those are exactly the nodes we want to show
   * move info for in 'svn status'. See also comments in svn_wc_status3_t. */
  if (status->moved_from_abspath && status->moved_to_abspath &&
      strcmp(status->moved_from_abspath, status->moved_to_abspath) == 0)
    {
      const char *relpath;

      relpath = make_relpath(cwd_abspath, status->moved_from_abspath,
                             pool, pool);
      relpath = svn_dirent_local_style(relpath, pool);
      moved_from_line = apr_pstrcat(pool, "\n        > ",
                                    apr_psprintf(pool,
                                                 _("swapped places with %s"),
                                                 relpath),
                                    (char *)NULL);
    }
  else if (status->moved_from_abspath || status->moved_to_abspath)
    {
      const char *relpath;

      if (status->moved_from_abspath)
        {
          relpath = make_relpath(cwd_abspath, status->moved_from_abspath,
                                 pool, pool);
          relpath = svn_dirent_local_style(relpath, pool);
          moved_from_line = apr_pstrcat(pool, "\n        > ",
                                        apr_psprintf(pool, _("moved from %s"),
                                                     relpath),
                                        (char *)NULL);
        }

      if (status->moved_to_abspath)
        {
          relpath = make_relpath(cwd_abspath, status->moved_to_abspath,
                                 pool, pool);
          relpath = svn_dirent_local_style(relpath, pool);
          moved_to_line = apr_pstrcat(pool, "\n        > ",
                                      apr_psprintf(pool, _("moved to %s"),
                                                   relpath),
                                      (char *)NULL);
        }
    }

  if (detailed)
    {
      char ood_status, lock_status;
      const char *working_rev;

      if (! status->versioned)
        working_rev = "";
      else if (status->copied
               || ! SVN_IS_VALID_REVNUM(status->revision))
        working_rev = "-";
      else
        working_rev = apr_psprintf(pool, "%ld", status->revision);

      if (status->repos_node_status != svn_wc_status_none)
        ood_status = '*';
      else
        ood_status = ' ';

      if (repos_locks)
        {
          if (status->repos_lock)
            {
              if (status->lock)
                {
                  if (strcmp(status->repos_lock->token, status->lock->token)
                      == 0)
                    lock_status = 'K';
                  else
                    lock_status = 'T';
                }
              else
                lock_status = 'O';
            }
          else if (status->lock)
            lock_status = 'B';
          else
            lock_status = ' ';
        }
      else
        lock_status = (status->lock) ? 'K' : ' ';

      if (show_last_committed)
        {
          const char *commit_rev;
          const char *commit_author;

          if (SVN_IS_VALID_REVNUM(status->changed_rev))
            commit_rev = apr_psprintf(pool, "%ld", status->changed_rev);
          else if (status->versioned)
            commit_rev = " ? ";
          else
            commit_rev = "";

          if (status->changed_author)
            commit_author = status->changed_author;
          else if (status->versioned)
            commit_author = " ? ";
          else
            commit_author = "";

          SVN_ERR
            (svn_cmdline_printf(pool,
                                "%c%c%c%c%c%c%c %c %8s %8s %-12s %s%s%s%s\n",
                                generate_status_code(combined_status(status)),
                                generate_status_code(prop_status),
                                status->wc_is_locked ? 'L' : ' ',
                                status->copied ? '+' : ' ',
                                generate_switch_column_code(status),
                                lock_status,
                                tree_status_code,
                                ood_status,
                                working_rev,
                                commit_rev,
                                commit_author,
                                path,
                                moved_to_line,
                                moved_from_line,
                                tree_desc_line));
        }
      else
        SVN_ERR(
           svn_cmdline_printf(pool, "%c%c%c%c%c%c%c %c %8s   %s%s%s%s\n",
                              generate_status_code(combined_status(status)),
                              generate_status_code(prop_status),
                              status->wc_is_locked ? 'L' : ' ',
                              status->copied ? '+' : ' ',
                              generate_switch_column_code(status),
                              lock_status,
                              tree_status_code,
                              ood_status,
                              working_rev,
                              path,
                              moved_to_line,
                              moved_from_line,
                              tree_desc_line));
    }
  else
    SVN_ERR(
       svn_cmdline_printf(pool, "%c%c%c%c%c%c%c %s%s%s%s\n",
                          generate_status_code(combined_status(status)),
                          generate_status_code(prop_status),
                          status->wc_is_locked ? 'L' : ' ',
                          status->copied ? '+' : ' ',
                          generate_switch_column_code(status),
                          ((status->lock)
                           ? 'K' : ' '),
                          tree_status_code,
                          path,
                          moved_to_line,
                          moved_from_line,
                          tree_desc_line));

  return svn_cmdline_fflush(stdout);
}
Ejemplo n.º 4
0
svn_error_t *
svn_wc__status2_from_3(svn_wc_status2_t **status,
                       const svn_wc_status3_t *old_status,
                       svn_wc_context_t *wc_ctx,
                       const char *local_abspath,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
{
  const svn_wc_entry_t *entry = NULL;

  if (old_status == NULL)
    {
      *status = NULL;
      return SVN_NO_ERROR;
    }

  *status = apr_pcalloc(result_pool, sizeof(**status));

  if (old_status->versioned)
    {
      svn_error_t *err;
      err= svn_wc__get_entry(&entry, wc_ctx->db, local_abspath, FALSE,
                             svn_node_unknown, result_pool, scratch_pool);

      if (err && err->apr_err == SVN_ERR_NODE_UNEXPECTED_KIND)
        svn_error_clear(err);
      else
        SVN_ERR(err);
    }

  (*status)->entry = entry;
  (*status)->copied = old_status->copied;
  (*status)->repos_lock = svn_lock_dup(old_status->repos_lock, result_pool);

  if (old_status->repos_relpath)
    (*status)->url = svn_path_url_add_component2(old_status->repos_root_url,
                                                 old_status->repos_relpath,
                                                 result_pool);
  (*status)->ood_last_cmt_rev = old_status->ood_changed_rev;
  (*status)->ood_last_cmt_date = old_status->ood_changed_date;
  (*status)->ood_kind = old_status->ood_kind;
  (*status)->ood_last_cmt_author = old_status->ood_changed_author;

  if (old_status->conflicted)
    {
      const svn_wc_conflict_description2_t *tree_conflict;
      SVN_ERR(svn_wc__get_tree_conflict(&tree_conflict, wc_ctx, local_abspath,
                                        scratch_pool, scratch_pool));
      (*status)->tree_conflict = svn_wc__cd2_to_cd(tree_conflict, result_pool);
    }

  (*status)->switched = old_status->switched;

  (*status)->text_status = old_status->node_status;
  (*status)->prop_status = old_status->prop_status;

  (*status)->repos_text_status = old_status->repos_node_status;
  (*status)->repos_prop_status = old_status->repos_prop_status;

  /* Some values might be inherited from properties */
  if (old_status->node_status == svn_wc_status_modified
      || old_status->node_status == svn_wc_status_conflicted)
    (*status)->text_status = old_status->text_status;

  /* (Currently a no-op, but just make sure it is ok) */
  if (old_status->repos_node_status == svn_wc_status_modified
      || old_status->repos_node_status == svn_wc_status_conflicted)
    (*status)->text_status = old_status->repos_text_status;

  if (old_status->node_status == svn_wc_status_added)
    (*status)->prop_status = svn_wc_status_none; /* No separate info */

  /* Find pristine_text_status value */
  switch (old_status->text_status)
    {
      case svn_wc_status_none:
      case svn_wc_status_normal:
      case svn_wc_status_modified:
        (*status)->pristine_text_status = old_status->text_status;
        break;
      case svn_wc_status_conflicted:
      default:
        /* ### Fetch compare data, or fall back to the documented
               not retrieved behavior? */
        (*status)->pristine_text_status = svn_wc_status_none;
        break;
    }

  /* Find pristine_prop_status value */
  switch (old_status->prop_status)
    {
      case svn_wc_status_none:
      case svn_wc_status_normal:
      case svn_wc_status_modified:
        if (old_status->node_status != svn_wc_status_added
            && old_status->node_status != svn_wc_status_deleted
            && old_status->node_status != svn_wc_status_replaced)
          {
            (*status)->pristine_prop_status = old_status->prop_status;
          }
        else
          (*status)->pristine_prop_status = svn_wc_status_none;
        break;
      case svn_wc_status_conflicted:
      default:
        /* ### Fetch compare data, or fall back to the documented
               not retrieved behavior? */
        (*status)->pristine_prop_status = svn_wc_status_none;
        break;
    }

  if (old_status->versioned
      && old_status->conflicted
      && old_status->node_status != svn_wc_status_obstructed
      && (old_status->kind == svn_node_file
          || old_status->node_status != svn_wc_status_missing))
    {
      svn_boolean_t text_conflict_p, prop_conflict_p;

      /* The entry says there was a conflict, but the user might have
         marked it as resolved by deleting the artifact files, so check
         for that. */
      SVN_ERR(svn_wc__internal_conflicted_p(&text_conflict_p,
                                            &prop_conflict_p,
                                            NULL,
                                            wc_ctx->db, local_abspath,
                                            scratch_pool));

      if (text_conflict_p)
        (*status)->text_status = svn_wc_status_conflicted;

      if (prop_conflict_p)
        (*status)->prop_status = svn_wc_status_conflicted;
    }

  return SVN_NO_ERROR;
}