/*
* revision_status.c: report the revision range and status of a working copy
*
* ====================================================================
* Copyright (c) 2003-2004 CollabNet. All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://subversion.tigris.org/license-1.html.
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
*
* This software consists of voluntary contributions made by many
* individuals. For exact contribution history, see the revision
* history and logs, available at http://subversion.tigris.org/.
* ====================================================================
*/
#include "svn_wc.h"
#include "svn_private_config.h"
/* A baton for analyze_status(). */
struct status_baton
{
svn_wc_revision_status_t *result; /* where to put the result */
svn_boolean_t committed; /* examine last committed revisions */
const char *wc_path; /* path whose URL we're looking for */
const char *wc_url; /* URL for the path whose URL we're looking for */
apr_pool_t *pool; /* pool in which to store alloc-needy things */
};
/* An svn_wc_status_func2_t callback function for analyzing status
structures. */
static void
analyze_status(void *baton,
const char *path,
svn_wc_status2_t *status)
{
struct status_baton *sb = baton;
if (! status->entry)
return;
/* Added files have a revision of no interest */
if (status->text_status != svn_wc_status_added)
{
svn_revnum_t item_rev = (sb->committed
? status->entry->cmt_rev
: status->entry->revision);
if (sb->result->min_rev == SVN_INVALID_REVNUM
|| item_rev < sb->result->min_rev)
sb->result->min_rev = item_rev;
if (sb->result->max_rev == SVN_INVALID_REVNUM
|| item_rev > sb->result->max_rev)
sb->result->max_rev = item_rev;
}
sb->result->switched |= status->switched;
sb->result->modified |= (status->text_status != svn_wc_status_normal);
sb->result->modified |= (status->prop_status != svn_wc_status_normal
&& status->prop_status != svn_wc_status_none);
if (sb->wc_path
&& (! sb->wc_url)
&& (strcmp(path, sb->wc_path) == 0)
&& (status->entry))
sb->wc_url = apr_pstrdup(sb->pool, status->entry->url);
}
svn_error_t *
svn_wc_revision_status(svn_wc_revision_status_t **result_p,
const char *wc_path,
const char *trail_url,
svn_boolean_t committed,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *pool)
{
struct status_baton sb;
const char *target;
svn_wc_adm_access_t *anchor_access, *target_access;
const svn_delta_editor_t *editor;
void *edit_baton;
svn_revnum_t edit_revision;
svn_wc_revision_status_t *result = apr_palloc(pool, sizeof(**result_p));
*result_p = result;
/* set result as nil */
result->min_rev = SVN_INVALID_REVNUM;
result->max_rev = SVN_INVALID_REVNUM;
result->switched = FALSE;
result->modified = FALSE;
/* initialize walking baton */
sb.result = result;
sb.committed = committed;
sb.wc_path = wc_path;
sb.wc_url = NULL;
sb.pool = pool;
SVN_ERR(svn_wc_adm_open_anchor(&anchor_access, &target_access, &target,
wc_path, FALSE, -1,
cancel_func, cancel_baton,
pool));
SVN_ERR(svn_wc_get_status_editor2(&editor, &edit_baton, NULL,
&edit_revision, anchor_access, target,
NULL /* config */,
TRUE /* recurse */,
TRUE /* get_all */,
FALSE /* no_ignore */,
analyze_status, &sb,
cancel_func, cancel_baton,
NULL /* traversal_info */,
pool));
SVN_ERR(editor->close_edit(edit_baton, pool));
SVN_ERR(svn_wc_adm_close(anchor_access));
if ((! result->switched) && (trail_url != NULL))
{
/* If the trailing part of the URL of the working copy directory
does not match the given trailing URL then the whole working
copy is switched. */
if (! sb.wc_url)
{
result->switched = TRUE;
}
else
{
apr_size_t len1 = strlen(trail_url);
apr_size_t len2 = strlen(sb.wc_url);
if ((len1 > len2) || strcmp(sb.wc_url + len2 - len1, trail_url))
result->switched = TRUE;
}
}
return SVN_NO_ERROR;
}
syntax highlighted by Code2HTML, v. 0.9.1