#include <apr_pools.h>
#include "svn_error.h"
#include "svn_ra.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "client.h"
#include "svn_private_config.h"
#include "private/svn_wc_private.h"
svn_error_t *
svn_client__get_revision_number(svn_revnum_t *revnum,
svn_revnum_t *youngest_rev,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
svn_ra_session_t *ra_session,
const svn_opt_revision_t *revision,
apr_pool_t *scratch_pool)
{
switch (revision->kind)
{
case svn_opt_revision_unspecified:
*revnum = SVN_INVALID_REVNUM;
break;
case svn_opt_revision_number:
*revnum = revision->value.number;
break;
case svn_opt_revision_head:
if (youngest_rev && SVN_IS_VALID_REVNUM(*youngest_rev))
{
*revnum = *youngest_rev;
}
else
{
if (! ra_session)
return svn_error_create(SVN_ERR_CLIENT_RA_ACCESS_REQUIRED,
NULL, NULL);
SVN_ERR(svn_ra_get_latest_revnum(ra_session, revnum, scratch_pool));
if (youngest_rev)
*youngest_rev = *revnum;
}
break;
case svn_opt_revision_working:
case svn_opt_revision_base:
{
svn_error_t *err;
if (local_abspath == NULL)
return svn_error_create(SVN_ERR_CLIENT_VERSIONED_PATH_REQUIRED,
NULL, NULL);
if (svn_path_is_url(local_abspath))
goto invalid_rev_arg;
err = svn_wc__node_get_commit_base_rev(revnum, wc_ctx,
local_abspath,
scratch_pool);
if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
{
svn_error_clear(err);
return svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, NULL,
_("'%s' is not under version control"),
svn_dirent_local_style(local_abspath,
scratch_pool));
}
else
SVN_ERR(err);
if (! SVN_IS_VALID_REVNUM(*revnum))
return svn_error_createf(SVN_ERR_CLIENT_BAD_REVISION, NULL,
_("Path '%s' has no committed "
"revision"),
svn_dirent_local_style(local_abspath,
scratch_pool));
}
break;
case svn_opt_revision_committed:
case svn_opt_revision_previous:
{
if (local_abspath == NULL)
return svn_error_create(SVN_ERR_CLIENT_VERSIONED_PATH_REQUIRED,
NULL, NULL);
if (svn_path_is_url(local_abspath))
goto invalid_rev_arg;
SVN_ERR(svn_wc__node_get_changed_info(revnum, NULL, NULL,
wc_ctx, local_abspath,
scratch_pool, scratch_pool));
if (! SVN_IS_VALID_REVNUM(*revnum))
return svn_error_createf(SVN_ERR_CLIENT_BAD_REVISION, NULL,
_("Path '%s' has no committed "
"revision"),
svn_dirent_local_style(local_abspath,
scratch_pool));
if (revision->kind == svn_opt_revision_previous)
(*revnum)--;
}
break;
case svn_opt_revision_date:
if (! ra_session)
return svn_error_create(SVN_ERR_CLIENT_RA_ACCESS_REQUIRED, NULL, NULL);
SVN_ERR(svn_ra_get_dated_revision(ra_session, revnum,
revision->value.date, scratch_pool));
break;
default:
return svn_error_createf(SVN_ERR_CLIENT_BAD_REVISION, NULL,
_("Unrecognized revision type requested for "
"'%s'"),
svn_dirent_local_style(local_abspath,
scratch_pool));
}
if (youngest_rev
&& (revision->kind == svn_opt_revision_head
|| revision->kind == svn_opt_revision_date)
&& SVN_IS_VALID_REVNUM(*youngest_rev)
&& SVN_IS_VALID_REVNUM(*revnum)
&& (*revnum > *youngest_rev))
*revnum = *youngest_rev;
return SVN_NO_ERROR;
invalid_rev_arg:
return svn_error_create(
SVN_ERR_CLIENT_BAD_REVISION, NULL,
_("PREV, BASE, or COMMITTED revision keywords are invalid for URL"));
}