📄 prop_commands.c
字号:
item->prop_hash = prop_hash;
*((svn_client_proplist_item_t **) apr_array_push (list)) = item;
}
}
/* Helper for the remote case of svn_client_proplist.
*
* Push a new 'svn_client_proplist_item_t *' item onto PROPLIST,
* containing the properties for "TARGET_PREFIX/TARGET_RELATIVE" in
* REVNUM, obtained using RA_LIB and SESSION. The item->node_name
* will be "TARGET_PREFIX/TARGET_RELATIVE", and the value will be a
* hash mapping 'const char *' property names onto 'svn_string_t *'
* property values.
*
* Allocate the new item and its contents in POOL.
* Do all looping, recursion, and temporary work in SCRATCHPOOL.
*
* KIND is the kind of the node at "TARGET_PREFIX/TARGET_RELATIVE".
*
* If RECURSE is true and KIND is svn_node_dir, then recurse.
*/
static svn_error_t *
remote_proplist (apr_array_header_t *proplist,
const char *target_prefix,
const char *target_relative,
svn_node_kind_t kind,
svn_revnum_t revnum,
svn_ra_plugin_t *ra_lib,
void *session,
svn_boolean_t recurse,
apr_pool_t *pool,
apr_pool_t *scratchpool)
{
apr_hash_t *dirents;
apr_hash_t *prop_hash, *final_hash;
apr_hash_index_t *hi;
if (kind == svn_node_dir)
{
SVN_ERR (ra_lib->get_dir (session, target_relative, revnum,
(recurse ? &dirents : NULL),
NULL, &prop_hash, scratchpool));
}
else if (kind == svn_node_file)
{
SVN_ERR (ra_lib->get_file (session, target_relative, revnum,
NULL, NULL, &prop_hash, scratchpool));
}
else
{
return svn_error_createf
(SVN_ERR_NODE_UNKNOWN_KIND, NULL,
_("Unknown node kind for '%s'"),
svn_path_join (target_prefix, target_relative, pool));
}
/* Filter out non-regular properties, since the RA layer returns all
kinds. Copy regular properties keys/vals from the prop_hash
allocated in SCRATCHPOOL to the "final" hash allocated in POOL. */
final_hash = apr_hash_make (pool);
for (hi = apr_hash_first (scratchpool, prop_hash);
hi;
hi = apr_hash_next (hi))
{
const void *key;
apr_ssize_t klen;
void *val;
svn_prop_kind_t prop_kind;
const char *name;
svn_string_t *value;
apr_hash_this (hi, &key, &klen, &val);
prop_kind = svn_property_kind (NULL, (const char *) key);
if (prop_kind == svn_prop_regular_kind)
{
name = apr_pstrdup (pool, (const char *) key);
value = svn_string_dup ((svn_string_t *) val, pool);
apr_hash_set (final_hash, name, klen, value);
}
}
push_props_on_list (proplist, final_hash,
svn_path_join (target_prefix, target_relative,
scratchpool),
pool);
if (recurse && (kind == svn_node_dir) && (apr_hash_count (dirents) > 0))
{
apr_pool_t *subpool = svn_pool_create (scratchpool);
for (hi = apr_hash_first (scratchpool, dirents);
hi;
hi = apr_hash_next (hi))
{
const void *key;
void *val;
const char *this_name;
svn_dirent_t *this_ent;
const char *new_target_relative;
svn_pool_clear (subpool);
apr_hash_this (hi, &key, NULL, &val);
this_name = key;
this_ent = val;
new_target_relative = svn_path_join (target_relative,
this_name, subpool);
SVN_ERR (remote_proplist (proplist,
target_prefix,
new_target_relative,
this_ent->kind,
revnum,
ra_lib,
session,
recurse,
pool,
subpool));
}
svn_pool_destroy (subpool);
}
return SVN_NO_ERROR;
}
/* Push an 'svn_client_proplist_item_t *' item onto PROP_LIST, where
* item->node_name is an 'svn_stringbuf_t *' created from NODE_NAME,
* and item->prop_hash is the property hash for NODE_NAME.
*
* If PRISTINE is true, get base props, else get working props.
*
* Allocate the item and its contents in POOL.
*/
static svn_error_t *
add_to_proplist (apr_array_header_t *prop_list,
const char *node_name,
svn_wc_adm_access_t *adm_access,
svn_boolean_t pristine,
apr_pool_t *pool)
{
apr_hash_t *hash;
SVN_ERR (pristine_or_working_props (&hash, node_name, adm_access, pristine,
pool));
push_props_on_list (prop_list, hash, node_name, pool);
return SVN_NO_ERROR;
}
/* A baton for proplist_walk_cb. */
struct proplist_walk_baton
{
svn_boolean_t pristine; /* Select base rather than working props. */
svn_wc_adm_access_t *base_access; /* Access for the tree being walked. */
apr_array_header_t *props; /* Out: array of svn_client_proplist_item_t. */
};
/* An entries-walk callback for svn_client_proplist.
*
* For the path given by PATH and ENTRY,
* populate wb->PROPS with a svn_client_proplist_item_t for each path,
* where "wb" is the WALK_BATON of type "struct proplist_walk_baton *".
* If wb->PRISTINE is true, use the base values, else use the working values.
*/
static svn_error_t *
proplist_walk_cb (const char *path,
const svn_wc_entry_t *entry,
void *walk_baton,
apr_pool_t *pool)
{
struct proplist_walk_baton *wb = 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 use
the second one (where we're looking at THIS_DIR). */
if ((entry->kind == svn_node_dir)
&& (strcmp (entry->name, SVN_WC_ENTRY_THIS_DIR) != 0))
return SVN_NO_ERROR;
/* Ignore the entry if it does not exist at the time of interest. */
if (entry->schedule
== (wb->pristine ? svn_wc_schedule_add : svn_wc_schedule_delete))
return SVN_NO_ERROR;
path = apr_pstrdup (wb->props->pool, path);
SVN_ERR (add_to_proplist (wb->props, path, wb->base_access,
wb->pristine, wb->props->pool));
return SVN_NO_ERROR;
}
/* Note: this implementation is very similar to svn_client_propget. */
svn_error_t *
svn_client_proplist (apr_array_header_t **props,
const char *target,
const svn_opt_revision_t *revision,
svn_boolean_t recurse,
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
svn_wc_adm_access_t *adm_access;
const svn_wc_entry_t *node;
const char *utarget; /* target, or the url for target */
const char *url;
svn_revnum_t revnum;
*props = apr_array_make (pool, 5, sizeof (svn_client_proplist_item_t *));
SVN_ERR (maybe_convert_to_url (&utarget, target, revision, pool));
/* Iff utarget is a url, that means we must use it, that is, the
requested property information is not available locally. */
if (svn_path_is_url (utarget))
{
void *session;
svn_ra_plugin_t *ra_lib;
svn_node_kind_t kind;
/* Get an RA plugin for this filesystem object. */
SVN_ERR (svn_client__ra_lib_from_path (&ra_lib, &session, &revnum,
&url, target, revision,
ctx, pool));
SVN_ERR (ra_lib->check_path (session, "", revnum, &kind, pool));
SVN_ERR (remote_proplist (*props, url, "",
kind, revnum, ra_lib, session,
recurse, pool, svn_pool_create (pool)));
}
else /* working copy path */
{
svn_boolean_t pristine;
SVN_ERR (svn_wc_adm_probe_open2 (&adm_access, NULL, target,
FALSE, recurse ? -1 : 0, pool));
SVN_ERR (svn_wc_entry (&node, target, adm_access, FALSE, pool));
if (! node)
return svn_error_createf
(SVN_ERR_UNVERSIONED_RESOURCE, NULL,
_("'%s' is not under version control"), target);
SVN_ERR (svn_client__get_revision_number
(&revnum, NULL, NULL, revision, target, pool));
if ((revision->kind == svn_opt_revision_committed)
|| (revision->kind == svn_opt_revision_base))
{
pristine = TRUE;
}
else /* must be the working revision */
{
pristine = FALSE;
}
/* Fetch, recursively or not. */
if (recurse && (node->kind == svn_node_dir))
{
static const svn_wc_entry_callbacks_t walk_callbacks
= { proplist_walk_cb };
struct proplist_walk_baton wb;
wb.base_access = adm_access;
wb.props = *props;
wb.pristine = pristine;
SVN_ERR (svn_wc_walk_entries (target, adm_access,
&walk_callbacks, &wb, FALSE, pool));
}
else
SVN_ERR (add_to_proplist (*props, target, adm_access, pristine, pool));
SVN_ERR (svn_wc_adm_close (adm_access));
}
return SVN_NO_ERROR;
}
svn_error_t *
svn_client_revprop_list (apr_hash_t **props,
const char *URL,
const svn_opt_revision_t *revision,
svn_revnum_t *set_rev,
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
void *ra_baton, *session;
svn_ra_plugin_t *ra_lib;
apr_hash_t *proplist;
/* Open an RA session for the URL. Note that we don't have a local
directory, nor a place to put temp files. */
SVN_ERR (svn_ra_init_ra_libs (&ra_baton, pool));
SVN_ERR (svn_ra_get_ra_library (&ra_lib, ra_baton, URL, pool));
SVN_ERR (svn_client__open_ra_session (&session, ra_lib, URL, NULL,
NULL, NULL, FALSE, TRUE,
ctx, pool));
/* Resolve the revision into something real, and return that to the
caller as well. */
SVN_ERR (svn_client__get_revision_number
(set_rev, ra_lib, session, revision, NULL, pool));
/* The actual RA call. */
SVN_ERR (ra_lib->rev_proplist (session, *set_rev, &proplist, pool));
*props = proplist;
return SVN_NO_ERROR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -