Exemplo n.º 1
0
svn_error_t *
svn_client__can_delete(const char *path,
                       svn_client_ctx_t *ctx,
                       apr_pool_t *scratch_pool)
{
    svn_opt_revision_t revision;
    svn_node_kind_t external_kind;
    const char *defining_abspath;
    const char* local_abspath;

    revision.kind = svn_opt_revision_unspecified;

    SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));

    /* A file external should not be deleted since the file external is
       implemented as a switched file and it would delete the file the
       file external is switched to, which is not the behavior the user
       would probably want. */
    SVN_ERR(svn_wc__read_external_info(&external_kind, &defining_abspath, NULL,
                                       NULL, NULL,
                                       ctx->wc_ctx, local_abspath,
                                       local_abspath, TRUE,
                                       scratch_pool, scratch_pool));

    if (external_kind != svn_node_none)
        return svn_error_createf(SVN_ERR_WC_CANNOT_DELETE_FILE_EXTERNAL, NULL,
                                 _("Cannot remove the external at '%s'; "
                                   "please edit or delete the svn:externals "
                                   "property on '%s'"),
                                 svn_dirent_local_style(local_abspath,
                                         scratch_pool),
                                 svn_dirent_local_style(defining_abspath,
                                         scratch_pool));


    /* Use an infinite-depth status check to see if there's anything in
       or under PATH which would make it unsafe for deletion.  The
       status callback function find_undeletables() makes the
       determination, returning an error if it finds anything that shouldn't
       be deleted. */
    return svn_error_trace(svn_client_status5(NULL, ctx, path, &revision,
                           svn_depth_infinity, FALSE,
                           FALSE, FALSE, FALSE, FALSE,
                           NULL,
                           find_undeletables, NULL,
                           scratch_pool));
}
Exemplo n.º 2
0
Arquivo: qsvn.cpp Projeto: bokic/qsvn
QString QSvn::urlFromPath(const QString &path)
{
    QString ret;
    svn_error_t *err = nullptr;
    QSvnPool localpool(pool);

    svn_opt_revision_t rev;
    rev.kind = svn_opt_revision_working;
    rev.value.number = 0;

    err = svn_client_status5(nullptr,
                             ctx,
                             path.toUtf8().constData(),
                             &rev,
                             svn_depth_empty,
                             true,
                             false,
                             true,
                             true,
                             false,
                             nullptr,
                             [](void *baton, const char *path, const svn_client_status_t *status, apr_pool_t *scratch_pool) -> svn_error_t * {
                                Q_UNUSED(path);
                                Q_UNUSED(status);
                                Q_UNUSED(scratch_pool);

                                QString *ret = (QString *)baton;

                                *ret = QString::fromUtf8(status->repos_root_url);

                                if (strlen(status->repos_relpath) > 0)
                                {
                                    *ret += "/" + QString::fromUtf8(status->repos_relpath);
                                }

                                return SVN_NO_ERROR;
                             },
                             (void *)&ret,
                             localpool);

    if (err)
    {
        emit error(err->message);
    }

    return ret;
}
Exemplo n.º 3
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. */
  rev.kind = svn_opt_revision_head;

  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_status5(&repos_rev, ctx, target, &rev,
                                             opt_state->depth,
                                             opt_state->verbose,
                                             opt_state->update,
                                             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,
                          SVN_NO_ERROR));

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

  /* 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_empty(scratch_pool);

      for (hi = apr_hash_first(scratch_pool, master_cl_hash); hi;
           hi = apr_hash_next(hi))
        {
          const char *changelist_name = svn__apr_hash_index_key(hi);
          apr_array_header_t *path_array = svn__apr_hash_index_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,
                                    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));
            }
        }
    }
Exemplo n.º 4
0
bool
CCachedDirectory::SvnUpdateMembersStatus()
{
    if (InterlockedExchange(&m_FetchingStatus, TRUE))
        return false;

    svn_opt_revision_t revision;
    revision.kind = svn_opt_revision_unspecified;

    SVNPool subPool(CSVNStatusCache::Instance().m_svnHelp.Pool());
    CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": stat for %s\n"), m_directoryPath.GetWinPath());

    const char * svnapipath = m_directoryPath.GetSVNApiPath(subPool);
    if ((svnapipath == 0)||(svnapipath[0] == 0))
    {
        InterlockedExchange(&m_FetchingStatus, FALSE);
        m_currentFullStatus = m_mostImportantFileStatus = svn_wc_status_none;
        CSVNStatusCache::Instance().BlockPath(m_directoryPath, true, 5);
        return false;
    }
    m_pCtx = CSVNStatusCache::Instance().m_svnHelp.ClientContext(subPool);
    svn_error_t * pErr = nullptr;
    if (m_pCtx)
    {
        pErr = svn_client_status5 (
                                   NULL,
                                   m_pCtx,
                                   svnapipath,
                                   &revision,
                                   svn_depth_immediates,
                                   TRUE,       // get all
                                   FALSE,      // update
                                   TRUE,       // no ignores
                                   FALSE,      // ignore externals
                                   TRUE,       // depth as sticky
                                   NULL,       // changelists
                                   GetStatusCallback,
                                   this,
                                   subPool
                                   );

        svn_wc_context_destroy(m_pCtx->wc_ctx);
        m_pCtx->wc_ctx = NULL;
        m_pCtx = NULL;
    }
    else
    {
        CTraceToOutputDebugString::Instance()(__FUNCTION__ ": error creating client context!\n");
        m_currentFullStatus = m_mostImportantFileStatus = svn_wc_status_none;
        // Since we only assume a none status here due to the fact that we couldn't get a client context,
        // make sure that this status times out soon.
        CSVNStatusCache::Instance().m_folderCrawler.BlockPath(m_directoryPath, 20);
        CSVNStatusCache::Instance().AddFolderForCrawling(m_directoryPath);
    }
    InterlockedExchange(&m_FetchingStatus, FALSE);
    if (pErr)
    {
        // Handle an error
        // The most likely error on a folder is that it's not part of a WC
        // In most circumstances, this will have been caught earlier,
        // but in some situations, we'll get this error.
        // If we allow ourselves to fall on through, then folders will be asked
        // for their own status, and will set themselves as unversioned, for the
        // benefit of future requests
        CTraceToOutputDebugString::Instance()(__FUNCTION__ ": svn_cli_stat error '%s'\n", pErr->message);
        // No assert here! Since we _can_ get here, an assertion is not an option!
        // Reasons to get here:
        // - renaming a folder with many sub folders --> results in "not a working copy" if the revert
        //   happens between our checks and the svn_client_status() call.
        // - reverting a move/copy --> results in "not a working copy" (as above)
        switch (pErr->apr_err)
        {
        case SVN_ERR_WC_NOT_WORKING_COPY:
            {
                m_currentFullStatus = m_mostImportantFileStatus = svn_wc_status_none;
                CSVNStatusCache::Instance().BlockPath(m_directoryPath, true);
            }
            break;
        case SVN_ERR_WC_PATH_NOT_FOUND:
        case SVN_ERR_WC_NOT_FILE:
        case SVN_ERR_WC_CORRUPT:
        case SVN_ERR_WC_CORRUPT_TEXT_BASE:
        case SVN_ERR_WC_UNSUPPORTED_FORMAT:
        case SVN_ERR_WC_DB_ERROR:
        case SVN_ERR_WC_MISSING:
        case SVN_ERR_WC_PATH_UNEXPECTED_STATUS:
        case SVN_ERR_WC_UPGRADE_REQUIRED:
        case SVN_ERR_WC_CLEANUP_REQUIRED:
            {
                m_currentFullStatus = m_mostImportantFileStatus = svn_wc_status_none;
            }
            break;
        default:
            {
                // Since we only assume a none status here due to svn_client_status()
                // returning an error, make sure that this status times out soon.
                CSVNStatusCache::Instance().m_folderCrawler.BlockPath(m_directoryPath, 20);
                CSVNStatusCache::Instance().AddFolderForCrawling(m_directoryPath);
            }
            break;
        }
        svn_error_clear(pErr);

        return false;
    }

    RefreshMostImportant(false);
    return true;
}