#include <apr_pools.h>
#include <apr_time.h>
#include "svn_pools.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_hash.h"
#include "svn_types.h"
#include "wc.h"
#include "props.h"
#include "entries.h"
#include "wc_db.h"
#include "svn_private_config.h"
#include "private/svn_wc_private.h"
static svn_error_t *
filter_and_make_absolute(const apr_array_header_t **children_abspaths,
svn_wc_context_t *wc_ctx,
const char *dir_abspath,
const apr_array_header_t *rel_children,
svn_boolean_t show_hidden,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
apr_array_header_t *children;
int i;
children = apr_array_make(result_pool, rel_children->nelts,
sizeof(const char *));
for (i = 0; i < rel_children->nelts; i++)
{
const char *child_abspath = svn_dirent_join(dir_abspath,
APR_ARRAY_IDX(rel_children,
i,
const char *),
result_pool);
if (!show_hidden)
{
svn_boolean_t child_is_hidden;
SVN_ERR(svn_wc__db_node_hidden(&child_is_hidden, wc_ctx->db,
child_abspath, scratch_pool));
if (child_is_hidden)
continue;
}
APR_ARRAY_PUSH(children, const char *) = child_abspath;
}
*children_abspaths = children;
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__node_get_children_of_working_node(const apr_array_header_t **children,
svn_wc_context_t *wc_ctx,
const char *dir_abspath,
svn_boolean_t show_hidden,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
const apr_array_header_t *rel_children;
SVN_ERR(svn_wc__db_read_children_of_working_node(&rel_children,
wc_ctx->db, dir_abspath,
scratch_pool, scratch_pool));
SVN_ERR(filter_and_make_absolute(children, wc_ctx, dir_abspath,
rel_children, show_hidden,
result_pool, scratch_pool));
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__node_get_children(const apr_array_header_t **children,
svn_wc_context_t *wc_ctx,
const char *dir_abspath,
svn_boolean_t show_hidden,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
const apr_array_header_t *rel_children;
SVN_ERR(svn_wc__db_read_children(&rel_children, wc_ctx->db, dir_abspath,
scratch_pool, scratch_pool));
SVN_ERR(filter_and_make_absolute(children, wc_ctx, dir_abspath,
rel_children, show_hidden,
result_pool, scratch_pool));
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__internal_get_repos_info(const char **repos_root_url,
const char **repos_uuid,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
svn_error_t *err;
svn_wc__db_status_t status;
err = svn_wc__db_read_info(&status, NULL, NULL, NULL,
repos_root_url, repos_uuid,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL,
db, local_abspath,
result_pool, scratch_pool);
if (err)
{
if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND
&& err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY)
return svn_error_trace(err);
svn_error_clear(err);
if (repos_root_url)
*repos_root_url = NULL;
if (repos_uuid)
*repos_uuid = NULL;
return SVN_NO_ERROR;
}
if (((repos_root_url && *repos_root_url) || !repos_root_url)
&& ((repos_uuid && *repos_uuid) || !repos_uuid))
return SVN_NO_ERROR;
if (status == svn_wc__db_status_deleted)
{
const char *base_del_abspath, *wrk_del_abspath;
SVN_ERR(svn_wc__db_scan_deletion(&base_del_abspath, NULL,
&wrk_del_abspath,
db, local_abspath,
scratch_pool, scratch_pool));
if (base_del_abspath)
SVN_ERR(svn_wc__db_scan_base_repos(NULL,repos_root_url,
repos_uuid, db, base_del_abspath,
result_pool, scratch_pool));
else if (wrk_del_abspath)
SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL,
repos_root_url, repos_uuid,
NULL, NULL, NULL, NULL,
db, svn_dirent_dirname(
wrk_del_abspath,
scratch_pool),
result_pool, scratch_pool));
}
else if (status == svn_wc__db_status_added)
{
SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL,
repos_root_url, repos_uuid,
NULL, NULL, NULL, NULL,
db, local_abspath,
result_pool, scratch_pool));
}
else
SVN_ERR(svn_wc__db_scan_base_repos(NULL, repos_root_url, repos_uuid,
db, local_abspath,
result_pool, scratch_pool));
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__node_get_repos_info(const char **repos_root_url,
const char **repos_uuid,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
return svn_error_trace(svn_wc__internal_get_repos_info(
repos_root_url, repos_uuid, wc_ctx->db, local_abspath,
result_pool, scratch_pool));
}
static svn_error_t *
convert_db_kind_to_node_kind(svn_node_kind_t *node_kind,
svn_wc__db_kind_t db_kind,
svn_wc__db_status_t db_status,
svn_boolean_t show_hidden)
{
switch (db_kind)
{
case svn_wc__db_kind_file:
*node_kind = svn_node_file;
break;
case svn_wc__db_kind_dir:
*node_kind = svn_node_dir;
break;
case svn_wc__db_kind_symlink:
*node_kind = svn_node_file;
break;
case svn_wc__db_kind_unknown:
*node_kind = svn_node_unknown;
break;
default:
SVN_ERR_MALFUNCTION();
}
if (! show_hidden)
switch (db_status)
{
case svn_wc__db_status_not_present:
case svn_wc__db_status_server_excluded:
case svn_wc__db_status_excluded:
*node_kind = svn_node_none;
default:
break;
}
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc_read_kind(svn_node_kind_t *kind,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
svn_boolean_t show_hidden,
apr_pool_t *scratch_pool)
{
svn_wc__db_status_t db_status;
svn_wc__db_kind_t db_kind;
svn_error_t *err;
err = svn_wc__db_read_info(&db_status, &db_kind, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
wc_ctx->db, local_abspath,
scratch_pool, scratch_pool);
if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
{
svn_error_clear(err);
*kind = svn_node_none;
return SVN_NO_ERROR;
}
else
SVN_ERR(err);
SVN_ERR(convert_db_kind_to_node_kind(kind, db_kind, db_status, show_hidden));
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__node_get_depth(svn_depth_t *depth,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *scratch_pool)
{
return svn_error_trace(
svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, depth, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
wc_ctx->db, local_abspath, scratch_pool,
scratch_pool));
}
svn_error_t *
svn_wc__node_get_changed_info(svn_revnum_t *changed_rev,
apr_time_t *changed_date,
const char **changed_author,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
return svn_error_trace(
svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL, changed_rev,
changed_date, changed_author, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
wc_ctx->db, local_abspath, result_pool,
scratch_pool));
}
svn_error_t *
svn_wc__node_get_url(const char **url,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
return svn_error_trace(svn_wc__db_read_url(url, wc_ctx->db, local_abspath,
result_pool, scratch_pool));
}
svn_error_t *
svn_wc__node_get_repos_relpath(const char **repos_relpath,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
svn_wc__db_status_t status;
svn_boolean_t have_base;
SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, repos_relpath,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
&have_base, NULL, NULL,
wc_ctx->db, local_abspath,
result_pool, scratch_pool));
if (*repos_relpath == NULL)
{
if (status == svn_wc__db_status_added)
{
SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, repos_relpath,
NULL, NULL, NULL, NULL,
NULL, NULL,
wc_ctx->db, local_abspath,
result_pool, scratch_pool));
}
else if (have_base)
{
SVN_ERR(svn_wc__db_scan_base_repos(repos_relpath, NULL,
NULL,
wc_ctx->db, local_abspath,
result_pool, scratch_pool));
}
else if (status == svn_wc__db_status_excluded
|| (!have_base && (status == svn_wc__db_status_deleted)))
{
const char *parent_abspath, *name, *parent_relpath;
svn_dirent_split(&parent_abspath, &name, local_abspath,
scratch_pool);
SVN_ERR(svn_wc__node_get_repos_relpath(&parent_relpath, wc_ctx,
parent_abspath,
scratch_pool,
scratch_pool));
if (parent_relpath)
*repos_relpath = svn_relpath_join(parent_relpath, name,
result_pool);
}
else
{
*repos_relpath = NULL;
return SVN_NO_ERROR;
}
}
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__internal_get_copyfrom_info(const char **copyfrom_root_url,
const char **copyfrom_repos_relpath,
const char **copyfrom_url,
svn_revnum_t *copyfrom_rev,
svn_boolean_t *is_copy_target,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
const char *original_root_url;
const char *original_repos_relpath;
svn_revnum_t original_revision;
svn_wc__db_status_t status;
if (copyfrom_root_url)
*copyfrom_root_url = NULL;
if (copyfrom_repos_relpath)
*copyfrom_repos_relpath = NULL;
if (copyfrom_url)
*copyfrom_url = NULL;
if (copyfrom_rev)
*copyfrom_rev = SVN_INVALID_REVNUM;
if (is_copy_target)
*is_copy_target = FALSE;
SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
&original_repos_relpath,
&original_root_url, NULL,
&original_revision,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL,
db, local_abspath, result_pool, scratch_pool));
if (original_root_url && original_repos_relpath)
{
const char *my_copyfrom_url;
if (copyfrom_url || is_copy_target)
my_copyfrom_url = svn_path_url_add_component2(original_root_url,
original_repos_relpath,
result_pool);
if (copyfrom_root_url)
*copyfrom_root_url = original_root_url;
if (copyfrom_repos_relpath)
*copyfrom_repos_relpath = original_repos_relpath;
if (copyfrom_url)
*copyfrom_url = my_copyfrom_url;
if (copyfrom_rev)
*copyfrom_rev = original_revision;
if (is_copy_target)
{
const char *parent_abspath;
const char *base_name;
const char *parent_copyfrom_url;
svn_dirent_split(&parent_abspath, &base_name, local_abspath,
scratch_pool);
SVN_ERR(svn_wc__internal_get_copyfrom_info(NULL, NULL,
&parent_copyfrom_url,
NULL, NULL,
db, parent_abspath,
scratch_pool,
scratch_pool));
if (parent_copyfrom_url == NULL
|| strcmp(my_copyfrom_url,
svn_path_url_add_component2(parent_copyfrom_url,
base_name,
scratch_pool)) != 0)
*is_copy_target = TRUE;
}
}
else if ((status == svn_wc__db_status_added)
&& (copyfrom_rev || copyfrom_url || copyfrom_root_url
|| copyfrom_repos_relpath))
{
const char *op_root_abspath;
SVN_ERR(svn_wc__db_scan_addition(&status, &op_root_abspath, NULL, NULL,
NULL, &original_repos_relpath,
&original_root_url, NULL,
&original_revision, db, local_abspath,
result_pool, scratch_pool));
if (status == svn_wc__db_status_copied ||
status == svn_wc__db_status_moved_here)
{
const char *src_parent_url;
const char *src_relpath;
src_parent_url = svn_path_url_add_component2(original_root_url,
original_repos_relpath,
scratch_pool);
src_relpath = svn_dirent_is_child(op_root_abspath, local_abspath,
scratch_pool);
if (src_relpath)
{
if (copyfrom_root_url)
*copyfrom_root_url = original_root_url;
if (copyfrom_repos_relpath)
*copyfrom_repos_relpath = svn_relpath_join(
original_repos_relpath,
src_relpath, result_pool);
if (copyfrom_url)
*copyfrom_url = svn_path_url_add_component2(src_parent_url,
src_relpath,
result_pool);
if (copyfrom_rev)
*copyfrom_rev = original_revision;
}
}
}
return SVN_NO_ERROR;
}
static svn_error_t *
walker_helper(svn_wc__db_t *db,
const char *dir_abspath,
svn_boolean_t show_hidden,
const apr_hash_t *changelist_filter,
svn_wc__node_found_func_t walk_callback,
void *walk_baton,
svn_depth_t depth,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *scratch_pool)
{
apr_hash_t *rel_children_info;
apr_hash_index_t *hi;
apr_pool_t *iterpool;
if (depth == svn_depth_empty)
return SVN_NO_ERROR;
SVN_ERR(svn_wc__db_read_children_walker_info(&rel_children_info, db,
dir_abspath, scratch_pool,
scratch_pool));
iterpool = svn_pool_create(scratch_pool);
for (hi = apr_hash_first(scratch_pool, rel_children_info);
hi;
hi = apr_hash_next(hi))
{
const char *child_name = svn__apr_hash_index_key(hi);
struct svn_wc__db_walker_info_t *wi = svn__apr_hash_index_val(hi);
svn_wc__db_kind_t child_kind = wi->kind;
svn_wc__db_status_t child_status = wi->status;
const char *child_abspath;
svn_pool_clear(iterpool);
if (cancel_func)
SVN_ERR(cancel_func(cancel_baton));
child_abspath = svn_dirent_join(dir_abspath, child_name, iterpool);
if (!show_hidden)
switch (child_status)
{
case svn_wc__db_status_not_present:
case svn_wc__db_status_server_excluded:
case svn_wc__db_status_excluded:
continue;
default:
break;
}
if ( (child_kind == svn_wc__db_kind_file
|| depth >= svn_depth_immediates)
&& svn_wc__internal_changelist_match(db, child_abspath,
changelist_filter,
scratch_pool) )
{
svn_node_kind_t kind;
SVN_ERR(convert_db_kind_to_node_kind(&kind, child_kind,
child_status, show_hidden));
SVN_ERR(walk_callback(child_abspath, kind, walk_baton, iterpool));
}
if (child_kind == svn_wc__db_kind_dir
&& depth >= svn_depth_immediates)
{
svn_depth_t depth_below_here = depth;
if (depth == svn_depth_immediates)
depth_below_here = svn_depth_empty;
SVN_ERR(walker_helper(db, child_abspath, show_hidden,
changelist_filter,
walk_callback, walk_baton,
depth_below_here,
cancel_func, cancel_baton,
iterpool));
}
}
svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__internal_walk_children(svn_wc__db_t *db,
const char *local_abspath,
svn_boolean_t show_hidden,
const apr_array_header_t *changelist_filter,
svn_wc__node_found_func_t walk_callback,
void *walk_baton,
svn_depth_t walk_depth,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *scratch_pool)
{
svn_wc__db_kind_t db_kind;
svn_node_kind_t kind;
svn_wc__db_status_t status;
apr_hash_t *changelist_hash = NULL;
SVN_ERR_ASSERT(walk_depth >= svn_depth_empty
&& walk_depth <= svn_depth_infinity);
if (changelist_filter && changelist_filter->nelts)
SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelist_filter,
scratch_pool));
SVN_ERR(svn_wc__db_read_info(&status, &db_kind, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
db, local_abspath, scratch_pool, scratch_pool));
SVN_ERR(convert_db_kind_to_node_kind(&kind, db_kind, status, show_hidden));
if (svn_wc__internal_changelist_match(db, local_abspath,
changelist_hash, scratch_pool))
SVN_ERR(walk_callback(local_abspath, kind, walk_baton, scratch_pool));
if (db_kind == svn_wc__db_kind_file
|| status == svn_wc__db_status_not_present
|| status == svn_wc__db_status_excluded
|| status == svn_wc__db_status_server_excluded)
return SVN_NO_ERROR;
if (db_kind == svn_wc__db_kind_dir)
{
return svn_error_trace(
walker_helper(db, local_abspath, show_hidden, changelist_hash,
walk_callback, walk_baton,
walk_depth, cancel_func, cancel_baton, scratch_pool));
}
return svn_error_createf(SVN_ERR_NODE_UNKNOWN_KIND, NULL,
_("'%s' has an unrecognized node kind"),
svn_dirent_local_style(local_abspath,
scratch_pool));
}
svn_error_t *
svn_wc__node_is_status_deleted(svn_boolean_t *is_deleted,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *scratch_pool)
{
svn_wc__db_status_t status;
SVN_ERR(svn_wc__db_read_info(&status,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
wc_ctx->db, local_abspath,
scratch_pool, scratch_pool));
*is_deleted = (status == svn_wc__db_status_deleted);
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__node_is_status_server_excluded(svn_boolean_t *is_server_excluded,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *scratch_pool)
{
svn_wc__db_status_t status;
SVN_ERR(svn_wc__db_read_info(&status,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
wc_ctx->db, local_abspath,
scratch_pool, scratch_pool));
*is_server_excluded = (status == svn_wc__db_status_server_excluded);
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__node_is_status_not_present(svn_boolean_t *is_not_present,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *scratch_pool)
{
svn_wc__db_status_t status;
SVN_ERR(svn_wc__db_read_info(&status,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
wc_ctx->db, local_abspath,
scratch_pool, scratch_pool));
*is_not_present = (status == svn_wc__db_status_not_present);
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__node_is_status_excluded(svn_boolean_t *is_excluded,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *scratch_pool)
{
svn_wc__db_status_t status;
SVN_ERR(svn_wc__db_read_info(&status,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
wc_ctx->db, local_abspath,
scratch_pool, scratch_pool));
*is_excluded = (status == svn_wc__db_status_excluded);
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__node_is_added(svn_boolean_t *is_added,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *scratch_pool)
{
svn_wc__db_status_t status;
SVN_ERR(svn_wc__db_read_info(&status,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
wc_ctx->db, local_abspath,
scratch_pool, scratch_pool));
*is_added = (status == svn_wc__db_status_added);
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__node_has_working(svn_boolean_t *has_working,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *scratch_pool)
{
svn_wc__db_status_t status;
SVN_ERR(svn_wc__db_read_info(&status,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, has_working,
wc_ctx->db, local_abspath,
scratch_pool, scratch_pool));
return SVN_NO_ERROR;
}
static svn_error_t *
get_base_rev(svn_revnum_t *base_revision,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *scratch_pool)
{
svn_boolean_t have_base;
svn_error_t *err;
err = svn_wc__db_base_get_info(NULL, NULL, base_revision, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
db, local_abspath,
scratch_pool, scratch_pool);
if (!err || err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
return svn_error_trace(err);
svn_error_clear(err);
SVN_ERR(svn_wc__db_read_info(NULL, NULL, base_revision,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, &have_base, NULL,
NULL, NULL, NULL, NULL, NULL,
db, local_abspath,
scratch_pool, scratch_pool));
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__node_get_base_rev(svn_revnum_t *base_revision,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *scratch_pool)
{
return svn_error_trace(get_base_rev(base_revision, wc_ctx->db,
local_abspath, scratch_pool));
}
svn_error_t *
svn_wc__node_get_pre_ng_status_data(svn_revnum_t *revision,
svn_revnum_t *changed_rev,
apr_time_t *changed_date,
const char **changed_author,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
svn_wc__db_status_t status;
svn_boolean_t have_base, have_more_work, have_work;
SVN_ERR(svn_wc__db_read_info(&status, NULL, revision, NULL, NULL, NULL,
changed_rev, changed_date, changed_author,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
&have_base, &have_more_work, &have_work,
wc_ctx->db, local_abspath,
result_pool, scratch_pool));
if (!have_work
|| ((!changed_rev || SVN_IS_VALID_REVNUM(*changed_rev))
&& (!revision || SVN_IS_VALID_REVNUM(*revision)))
|| ((status != svn_wc__db_status_added)
&& (status != svn_wc__db_status_deleted)))
{
return SVN_NO_ERROR;
}
if (have_base && !have_more_work)
SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, revision, NULL, NULL, NULL,
changed_rev, changed_date, changed_author,
NULL, NULL, NULL,
NULL, NULL, NULL,
wc_ctx->db, local_abspath,
result_pool, scratch_pool));
else
{
}
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__internal_get_commit_base_rev(svn_revnum_t *commit_base_revision,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *scratch_pool)
{
svn_wc__db_status_t status;
svn_boolean_t have_base;
svn_boolean_t have_more_work;
svn_revnum_t revision;
svn_revnum_t original_revision;
*commit_base_revision = SVN_INVALID_REVNUM;
SVN_ERR(svn_wc__db_read_info(&status, NULL, &revision, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, &original_revision, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
&have_base, &have_more_work, NULL,
db, local_abspath, scratch_pool, scratch_pool));
if (SVN_IS_VALID_REVNUM(revision))
{
*commit_base_revision = revision;
return SVN_NO_ERROR;
}
else if (SVN_IS_VALID_REVNUM(original_revision))
{
*commit_base_revision = original_revision;
return SVN_NO_ERROR;
}
if (status == svn_wc__db_status_added)
{
SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, commit_base_revision,
db, local_abspath,
scratch_pool, scratch_pool));
if (SVN_IS_VALID_REVNUM(*commit_base_revision))
return SVN_NO_ERROR;
}
else if (status == svn_wc__db_status_deleted)
{
const char *work_del_abspath;
SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL,
&work_del_abspath,
db, local_abspath,
scratch_pool, scratch_pool));
if (work_del_abspath != NULL)
{
SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL,
commit_base_revision,
db,
svn_dirent_dirname(work_del_abspath,
scratch_pool),
scratch_pool, scratch_pool));
SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(*commit_base_revision));
return SVN_NO_ERROR;
}
}
if (have_base && !have_more_work)
{
SVN_ERR(svn_wc__db_base_get_info(&status, NULL, commit_base_revision,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
db, local_abspath,
scratch_pool, scratch_pool));
if (status == svn_wc__db_status_not_present)
*commit_base_revision = SVN_INVALID_REVNUM;
}
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__node_get_commit_base_rev(svn_revnum_t *commit_base_revision,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *scratch_pool)
{
return svn_error_trace(svn_wc__internal_get_commit_base_rev(
commit_base_revision, wc_ctx->db, local_abspath,
scratch_pool));
}
svn_error_t *
svn_wc__node_get_lock_info(const char **lock_token,
const char **lock_owner,
const char **lock_comment,
apr_time_t *lock_date,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
svn_wc__db_lock_t *lock;
svn_error_t *err;
err = svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, &lock, NULL,
NULL,
wc_ctx->db, local_abspath,
result_pool, scratch_pool);
if (err)
{
if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
return svn_error_trace(err);
svn_error_clear(err);
lock = NULL;
}
if (lock_token)
*lock_token = lock ? lock->token : NULL;
if (lock_owner)
*lock_owner = lock ? lock->owner : NULL;
if (lock_comment)
*lock_comment = lock ? lock->comment : NULL;
if (lock_date)
*lock_date = lock ? lock->date : 0;
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__internal_node_get_schedule(svn_wc_schedule_t *schedule,
svn_boolean_t *copied,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *scratch_pool)
{
svn_wc__db_status_t status;
svn_boolean_t op_root;
svn_boolean_t have_base;
svn_boolean_t have_work;
svn_boolean_t have_more_work;
const char *copyfrom_relpath;
if (schedule)
*schedule = svn_wc_schedule_normal;
if (copied)
*copied = FALSE;
SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, ©from_relpath,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
&op_root, NULL, NULL,
&have_base, &have_more_work, &have_work,
db, local_abspath, scratch_pool, scratch_pool));
switch (status)
{
case svn_wc__db_status_not_present:
case svn_wc__db_status_server_excluded:
case svn_wc__db_status_excluded:
if (schedule)
*schedule = svn_wc_schedule_normal;
break;
case svn_wc__db_status_normal:
case svn_wc__db_status_incomplete:
break;
case svn_wc__db_status_deleted:
{
if (schedule)
*schedule = svn_wc_schedule_delete;
if (!copied)
break;
if (have_more_work || !have_base)
*copied = TRUE;
else
{
const char *work_del_abspath;
SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL,
&work_del_abspath,
db, local_abspath,
scratch_pool, scratch_pool));
if (work_del_abspath)
*copied = TRUE;
}
break;
}
case svn_wc__db_status_added:
{
if (!op_root)
{
if (copied)
*copied = TRUE;
if (schedule)
*schedule = svn_wc_schedule_normal;
break;
}
if (copied)
*copied = (copyfrom_relpath != NULL);
if (schedule)
*schedule = svn_wc_schedule_add;
else
break;
if (have_base || have_more_work)
{
svn_wc__db_status_t below_working;
SVN_ERR(svn_wc__db_info_below_working(&have_base, &have_work,
&below_working,
db, local_abspath,
scratch_pool));
if (below_working != svn_wc__db_status_not_present
&& below_working != svn_wc__db_status_deleted)
{
*schedule = svn_wc_schedule_replace;
break;
}
}
break;
}
default:
SVN_ERR_MALFUNCTION();
}
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__node_get_schedule(svn_wc_schedule_t *schedule,
svn_boolean_t *copied,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *scratch_pool)
{
return svn_error_trace(
svn_wc__internal_node_get_schedule(schedule,
copied,
wc_ctx->db,
local_abspath,
scratch_pool));
}
svn_error_t *
svn_wc__node_get_conflict_info(const char **conflict_old,
const char **conflict_new,
const char **conflict_wrk,
const char **prejfile,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
svn_boolean_t conflicted;
SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, &conflicted,
NULL, NULL, NULL, NULL, NULL, NULL,
wc_ctx->db, local_abspath,
scratch_pool, scratch_pool));
if (conflict_old)
*conflict_old = NULL;
if (conflict_new)
*conflict_new = NULL;
if (conflict_wrk)
*conflict_wrk = NULL;
if (prejfile)
*prejfile = NULL;
if (conflicted
&& (conflict_old || conflict_new || conflict_wrk || prejfile))
{
const apr_array_header_t *conflicts;
int j;
SVN_ERR(svn_wc__db_read_conflicts(&conflicts, wc_ctx->db, local_abspath,
scratch_pool, scratch_pool));
for (j = 0; j < conflicts->nelts; j++)
{
const svn_wc_conflict_description2_t *cd;
cd = APR_ARRAY_IDX(conflicts, j,
const svn_wc_conflict_description2_t *);
switch (cd->kind)
{
case svn_wc_conflict_kind_text:
if (conflict_old)
*conflict_old = svn_dirent_basename(cd->base_abspath,
result_pool);
if (conflict_new)
*conflict_new = svn_dirent_basename(cd->their_abspath,
result_pool);
if (conflict_wrk)
*conflict_wrk = svn_dirent_basename(cd->my_abspath,
result_pool);
break;
case svn_wc_conflict_kind_property:
if (prejfile)
*prejfile = svn_dirent_basename(cd->their_abspath,
result_pool);
break;
case svn_wc_conflict_kind_tree:
break;
}
}
}
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__node_clear_dav_cache_recursive(svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *scratch_pool)
{
return svn_error_trace(svn_wc__db_base_clear_dav_cache_recursive(
wc_ctx->db, local_abspath, scratch_pool));
}
svn_error_t *
svn_wc__node_get_lock_tokens_recursive(apr_hash_t **lock_tokens,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
return svn_error_trace(svn_wc__db_base_get_lock_tokens_recursive(
lock_tokens, wc_ctx->db, local_abspath,
result_pool, scratch_pool));
}
svn_error_t *
svn_wc__get_server_excluded_subtrees(apr_hash_t **server_excluded_subtrees,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
return svn_error_trace(
svn_wc__db_get_server_excluded_subtrees(server_excluded_subtrees,
wc_ctx->db,
local_abspath,
result_pool,
scratch_pool));
}
svn_error_t *
svn_wc__internal_get_origin(svn_boolean_t *is_copy,
svn_revnum_t *revision,
const char **repos_relpath,
const char **repos_root_url,
const char **repos_uuid,
const char **copy_root_abspath,
svn_wc__db_t *db,
const char *local_abspath,
svn_boolean_t scan_deleted,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
const char *original_repos_relpath;
const char *original_repos_root_url;
const char *original_repos_uuid;
svn_revnum_t original_revision;
svn_wc__db_status_t status;
const char *tmp_repos_relpath;
if (!repos_relpath)
repos_relpath = &tmp_repos_relpath;
SVN_ERR(svn_wc__db_read_info(&status, NULL, revision, repos_relpath,
repos_root_url, repos_uuid, NULL, NULL, NULL,
NULL, NULL, NULL,
&original_repos_relpath,
&original_repos_root_url,
&original_repos_uuid, &original_revision,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, is_copy,
db, local_abspath, result_pool, scratch_pool));
if (*repos_relpath)
{
return SVN_NO_ERROR;
}
if (status == svn_wc__db_status_deleted && !scan_deleted)
{
if (is_copy)
*is_copy = FALSE;
return SVN_NO_ERROR;
}
if (original_repos_relpath)
{
*repos_relpath = original_repos_relpath;
if (revision)
*revision = original_revision;
if (repos_root_url)
*repos_root_url = original_repos_root_url;
if (repos_uuid)
*repos_uuid = original_repos_uuid;
if (copy_root_abspath == NULL)
return SVN_NO_ERROR;
}
{
svn_boolean_t scan_working = FALSE;
if (status == svn_wc__db_status_added)
scan_working = TRUE;
else if (status == svn_wc__db_status_deleted)
{
svn_boolean_t have_base;
SVN_ERR(svn_wc__db_info_below_working(&have_base, &scan_working,
&status, db, local_abspath,
scratch_pool));
}
if (scan_working)
{
const char *op_root_abspath;
SVN_ERR(svn_wc__db_scan_addition(&status, &op_root_abspath, NULL,
NULL, NULL, &original_repos_relpath,
repos_root_url,
repos_uuid,
revision, db, local_abspath,
result_pool, scratch_pool));
if (status == svn_wc__db_status_added)
{
if (is_copy)
*is_copy = FALSE;
return SVN_NO_ERROR;
}
if (status == svn_wc__db_status_incomplete && !original_repos_relpath)
return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
_("Incomplete copy information on path '%s'."),
svn_dirent_local_style(local_abspath,
scratch_pool));
*repos_relpath = svn_relpath_join(
original_repos_relpath,
svn_dirent_skip_ancestor(op_root_abspath,
local_abspath),
result_pool);
if (copy_root_abspath)
*copy_root_abspath = op_root_abspath;
}
else
{
if (is_copy)
*is_copy = FALSE;
SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, revision, repos_relpath,
repos_root_url, repos_uuid, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL,
db, local_abspath,
result_pool, scratch_pool));
}
return SVN_NO_ERROR;
}
}
svn_error_t *
svn_wc__node_get_origin(svn_boolean_t *is_copy,
svn_revnum_t *revision,
const char **repos_relpath,
const char **repos_root_url,
const char **repos_uuid,
const char **copy_root_abspath,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
svn_boolean_t scan_deleted,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
return svn_error_trace(svn_wc__internal_get_origin(is_copy, revision,
repos_relpath, repos_root_url, repos_uuid,
copy_root_abspath,
wc_ctx->db, local_abspath, scan_deleted,
result_pool, scratch_pool));
}
svn_error_t *
svn_wc__node_get_commit_status(svn_node_kind_t *kind,
svn_boolean_t *added,
svn_boolean_t *deleted,
svn_boolean_t *is_replace_root,
svn_boolean_t *not_present,
svn_boolean_t *excluded,
svn_boolean_t *is_op_root,
svn_boolean_t *symlink,
svn_revnum_t *revision,
const char **repos_relpath,
svn_revnum_t *original_revision,
const char **original_repos_relpath,
svn_boolean_t *conflicted,
const char **changelist,
svn_boolean_t *props_mod,
svn_boolean_t *update_root,
const char **lock_token,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
svn_wc__db_status_t status;
svn_wc__db_kind_t db_kind;
svn_wc__db_lock_t *lock;
svn_boolean_t had_props;
svn_boolean_t props_mod_tmp;
svn_boolean_t have_base;
svn_boolean_t have_more_work;
svn_boolean_t op_root;
if (!props_mod)
props_mod = &props_mod_tmp;
SVN_ERR(svn_wc__db_read_info(&status, &db_kind, revision, repos_relpath,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
original_repos_relpath, NULL, NULL,
original_revision, &lock, NULL, NULL,
changelist, conflicted,
&op_root, &had_props, props_mod,
&have_base, &have_more_work, NULL,
wc_ctx->db, local_abspath,
result_pool, scratch_pool));
if (kind)
{
if (db_kind == svn_wc__db_kind_file)
*kind = svn_node_file;
else if (db_kind == svn_wc__db_kind_dir)
*kind = svn_node_dir;
else
*kind = svn_node_unknown;
}
if (added)
*added = (status == svn_wc__db_status_added);
if (deleted)
*deleted = (status == svn_wc__db_status_deleted);
if (not_present)
*not_present = (status == svn_wc__db_status_not_present);
if (excluded)
*excluded = (status == svn_wc__db_status_excluded);
if (is_op_root)
*is_op_root = op_root;
if (is_replace_root)
{
if (status == svn_wc__db_status_added
&& op_root
&& (have_base || have_more_work))
SVN_ERR(svn_wc__db_node_check_replace(is_replace_root, NULL, NULL,
wc_ctx->db, local_abspath,
scratch_pool));
else
*is_replace_root = FALSE;
}
if (symlink)
{
apr_hash_t *props;
*symlink = FALSE;
if (db_kind == svn_wc__db_kind_file
&& (had_props || *props_mod))
{
SVN_ERR(svn_wc__db_read_props(&props, wc_ctx->db, local_abspath,
scratch_pool, scratch_pool));
*symlink = ((props != NULL)
&& (apr_hash_get(props, SVN_PROP_SPECIAL,
APR_HASH_KEY_STRING) != NULL));
}
}
if (have_base
&& ((revision && !SVN_IS_VALID_REVNUM(*revision))
|| (update_root && status == svn_wc__db_status_normal)))
{
SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, revision, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, update_root,
wc_ctx->db, local_abspath,
scratch_pool, scratch_pool));
}
else if (update_root)
*update_root = FALSE;
if (lock_token)
*lock_token = lock ? lock->token : NULL;
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__node_get_md5_from_sha1(const svn_checksum_t **md5_checksum,
svn_wc_context_t *wc_ctx,
const char *wri_abspath,
const svn_checksum_t *sha1_checksum,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
return svn_error_trace(svn_wc__db_pristine_get_md5(md5_checksum,
wc_ctx->db,
wri_abspath,
sha1_checksum,
result_pool,
scratch_pool));
}
svn_error_t *
svn_wc__get_not_present_descendants(const apr_array_header_t **descendants,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
return svn_error_trace(
svn_wc__db_get_not_present_descendants(descendants,
wc_ctx->db,
local_abspath,
result_pool,
scratch_pool));
}
svn_error_t *
svn_wc__rename_wc(svn_wc_context_t *wc_ctx,
const char *from_abspath,
const char *dst_abspath,
apr_pool_t *scratch_pool)
{
const char *wcroot_abspath;
SVN_ERR(svn_wc__db_get_wcroot(&wcroot_abspath, wc_ctx->db, from_abspath,
scratch_pool, scratch_pool));
if (! strcmp(from_abspath, wcroot_abspath))
{
SVN_ERR(svn_wc__db_drop_root(wc_ctx->db, wcroot_abspath, scratch_pool));
SVN_ERR(svn_io_file_rename(from_abspath, dst_abspath, scratch_pool));
}
else
return svn_error_createf(
SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
_("'%s' is not the root of the working copy '%s'"),
svn_dirent_local_style(from_abspath, scratch_pool),
svn_dirent_local_style(wcroot_abspath, scratch_pool));
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__check_for_obstructions(svn_wc_notify_state_t *obstruction_state,
svn_node_kind_t *kind,
svn_boolean_t *added,
svn_boolean_t *deleted,
svn_boolean_t *conflicted,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
svn_boolean_t no_wcroot_check,
apr_pool_t *scratch_pool)
{
svn_wc__db_status_t status;
svn_wc__db_kind_t db_kind;
svn_node_kind_t disk_kind;
svn_boolean_t conflicted_p;
svn_error_t *err;
*obstruction_state = svn_wc_notify_state_inapplicable;
if (kind)
*kind = svn_node_none;
if (added)
*added = FALSE;
if (deleted)
*deleted = FALSE;
if (conflicted)
*conflicted = FALSE;
SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, scratch_pool));
err = svn_wc__db_read_info(&status, &db_kind, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, &conflicted_p, NULL,
NULL, NULL, NULL, NULL, NULL,
wc_ctx->db, local_abspath,
scratch_pool, scratch_pool);
if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
{
svn_error_clear(err);
if (disk_kind != svn_node_none)
{
*obstruction_state = svn_wc_notify_state_obstructed;
return SVN_NO_ERROR;
}
err = svn_wc__db_read_info(&status, &db_kind, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
wc_ctx->db, svn_dirent_dirname(local_abspath,
scratch_pool),
scratch_pool, scratch_pool);
if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
{
svn_error_clear(err);
*obstruction_state = svn_wc_notify_state_obstructed;
return SVN_NO_ERROR;
}
else
SVN_ERR(err);
if (db_kind != svn_wc__db_kind_dir
|| (status != svn_wc__db_status_normal
&& status != svn_wc__db_status_added))
{
*obstruction_state = svn_wc_notify_state_obstructed;
}
return SVN_NO_ERROR;
}
else
SVN_ERR(err);
if (!no_wcroot_check
&& db_kind == svn_wc__db_kind_dir
&& status == svn_wc__db_status_normal)
{
svn_boolean_t is_root;
SVN_ERR(svn_wc__db_is_wcroot(&is_root, wc_ctx->db, local_abspath,
scratch_pool));
if (is_root)
{
*obstruction_state = svn_wc_notify_state_obstructed;
return SVN_NO_ERROR;
}
}
if (kind)
SVN_ERR(convert_db_kind_to_node_kind(kind, db_kind, status, FALSE));
switch (status)
{
case svn_wc__db_status_deleted:
if (deleted)
*deleted = TRUE;
case svn_wc__db_status_not_present:
if (disk_kind != svn_node_none)
*obstruction_state = svn_wc_notify_state_obstructed;
break;
case svn_wc__db_status_excluded:
case svn_wc__db_status_server_excluded:
case svn_wc__db_status_incomplete:
*obstruction_state = svn_wc_notify_state_missing;
break;
case svn_wc__db_status_added:
if (added)
*added = TRUE;
case svn_wc__db_status_normal:
if (disk_kind == svn_node_none)
*obstruction_state = svn_wc_notify_state_missing;
else
{
svn_node_kind_t expected_kind;
SVN_ERR(convert_db_kind_to_node_kind(&expected_kind, db_kind,
status, FALSE));
if (disk_kind != expected_kind)
*obstruction_state = svn_wc_notify_state_obstructed;
}
break;
default:
SVN_ERR_MALFUNCTION();
}
if (conflicted_p && (conflicted != NULL))
{
svn_boolean_t text_c, prop_c, tree_c;
SVN_ERR(svn_wc__internal_conflicted_p(&text_c, &prop_c, &tree_c,
wc_ctx->db, local_abspath,
scratch_pool));
*conflicted = (text_c || prop_c || tree_c);
}
return SVN_NO_ERROR;
}