You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by as...@apache.org on 2012/11/24 21:29:48 UTC
svn commit: r1413258 [8/33] - in /subversion/branches/compressed-pristines:
./ build/ build/ac-macros/ build/generator/ build/generator/templates/
contrib/client-side/emacs/ contrib/server-side/fsfsfixer/ notes/
notes/directory-index/ subversion/ subve...
Modified: subversion/branches/compressed-pristines/subversion/libsvn_client/prop_commands.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_client/prop_commands.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_client/prop_commands.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_client/prop_commands.c Sat Nov 24 20:29:11 2012
@@ -38,6 +38,7 @@
#include "svn_pools.h"
#include "svn_props.h"
#include "svn_hash.h"
+#include "svn_sorts.h"
#include "svn_private_config.h"
#include "private/svn_wc_private.h"
@@ -355,11 +356,9 @@ svn_client_propset_local(const char *pro
ctx->notify_func2(ctx->notify_baton2, notify, iterpool);
}
-
- svn_error_clear(err);
}
- else
- SVN_ERR(err);
+
+ SVN_ERR(err);
SVN_WC__CALL_WITH_WRITE_LOCK(
svn_wc_prop_set4(ctx->wc_ctx, target_abspath, propname,
@@ -594,21 +593,28 @@ pristine_or_working_props(apr_hash_t **p
/* Helper for the remote case of svn_client_propget.
*
- * Get the value of property PROPNAME in REVNUM, using RA_LIB and
- * SESSION. Store the value ('svn_string_t *') in PROPS, under the
- * path key "TARGET_PREFIX/TARGET_RELATIVE" ('const char *').
+ * If PROPS is not null, then get the value of property PROPNAME in REVNUM,
+ using RA_LIB and SESSION. Store the value ('svn_string_t *') in PROPS,
+ under the path key "TARGET_PREFIX/TARGET_RELATIVE" ('const char *').
+ *
+ * If INHERITED_PROPS is not null, then set *INHERITED_PROPS to a
+ * depth-first ordered array of svn_prop_inherited_item_t * structures
+ * representing the PROPNAME properties inherited by the target. If
+ * INHERITABLE_PROPS in not null and no inheritable properties are found,
+ * then set *INHERITED_PROPS to an empty array.
*
* Recurse according to DEPTH, similarly to svn_client_propget3().
*
* KIND is the kind of the node at "TARGET_PREFIX/TARGET_RELATIVE".
* Yes, caller passes this; it makes the recursion more efficient :-).
*
- * Allocate the keys and values in PERM_POOL, but do all temporary
- * work in WORK_POOL. The two pools can be the same; recursive
- * calls may use a different WORK_POOL, however.
+ * Allocate PROPS and *INHERITED_PROPS in RESULT_POOL, but do all temporary
+ * work in SCRATCH_POOL. The two pools can be the same; recursive
+ * calls may use a different SCRATCH_POOL, however.
*/
static svn_error_t *
remote_propget(apr_hash_t *props,
+ apr_array_header_t **inherited_props,
const char *propname,
const char *target_prefix,
const char *target_relative,
@@ -616,26 +622,27 @@ remote_propget(apr_hash_t *props,
svn_revnum_t revnum,
svn_ra_session_t *ra_session,
svn_depth_t depth,
- apr_pool_t *perm_pool,
- apr_pool_t *work_pool)
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
apr_hash_t *dirents;
- apr_hash_t *prop_hash;
+ apr_hash_t *prop_hash = NULL;
const svn_string_t *val;
const char *target_full_url =
- svn_path_url_add_component2(target_prefix, target_relative, work_pool);
+ svn_path_url_add_component2(target_prefix, target_relative,
+ scratch_pool);
if (kind == svn_node_dir)
{
SVN_ERR(svn_ra_get_dir2(ra_session,
(depth >= svn_depth_files ? &dirents : NULL),
NULL, &prop_hash, target_relative, revnum,
- SVN_DIRENT_KIND, work_pool));
+ SVN_DIRENT_KIND, scratch_pool));
}
else if (kind == svn_node_file)
{
SVN_ERR(svn_ra_get_file(ra_session, target_relative, revnum,
- NULL, NULL, &prop_hash, work_pool));
+ NULL, NULL, &prop_hash, scratch_pool));
}
else if (kind == svn_node_none)
{
@@ -650,10 +657,52 @@ remote_propget(apr_hash_t *props,
target_full_url);
}
- if ((val = apr_hash_get(prop_hash, propname, APR_HASH_KEY_STRING)))
+ if (inherited_props)
+ {
+ /* We will filter out all but PROPNAME later, making a final copy
+ in RESULT_POOL, so pass SCRATCH_POOL for both pools. */
+ SVN_ERR(svn_ra_get_inherited_props(ra_session, inherited_props,
+ target_relative, revnum,
+ scratch_pool, scratch_pool));
+ }
+
+ /* Make a copy of any inherited PROPNAME properties in RESULT_POOL. */
+ if (inherited_props)
+ {
+ int i;
+ apr_array_header_t *final_iprops =
+ apr_array_make(result_pool, 1, sizeof(svn_prop_inherited_item_t *));
+
+ for (i = 0; i < (*inherited_props)->nelts; i++)
+ {
+ svn_prop_inherited_item_t *iprop =
+ APR_ARRAY_IDX((*inherited_props), i, svn_prop_inherited_item_t *);
+ svn_string_t *iprop_val = apr_hash_get(iprop->prop_hash, propname,
+ APR_HASH_KEY_STRING);
+
+ if (iprop_val)
+ {
+ svn_prop_inherited_item_t *new_iprop =
+ apr_palloc(result_pool, sizeof(*new_iprop));
+ new_iprop->path_or_url =
+ apr_pstrdup(result_pool, iprop->path_or_url);
+ new_iprop->prop_hash = apr_hash_make(result_pool);
+ apr_hash_set(new_iprop->prop_hash,
+ apr_pstrdup(result_pool, propname),
+ APR_HASH_KEY_STRING,
+ svn_string_dup(iprop_val, result_pool));
+ APR_ARRAY_PUSH(final_iprops, svn_prop_inherited_item_t *) =
+ new_iprop;
+ }
+ }
+ *inherited_props = final_iprops;
+ }
+
+ if (prop_hash
+ && (val = apr_hash_get(prop_hash, propname, APR_HASH_KEY_STRING)))
{
- apr_hash_set(props, apr_pstrdup(perm_pool, target_full_url),
- APR_HASH_KEY_STRING, svn_string_dup(val, perm_pool));
+ apr_hash_set(props, apr_pstrdup(result_pool, target_full_url),
+ APR_HASH_KEY_STRING, svn_string_dup(val, result_pool));
}
if (depth >= svn_depth_files
@@ -661,9 +710,9 @@ remote_propget(apr_hash_t *props,
&& apr_hash_count(dirents) > 0)
{
apr_hash_index_t *hi;
- apr_pool_t *iterpool = svn_pool_create(work_pool);
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
- for (hi = apr_hash_first(work_pool, dirents);
+ for (hi = apr_hash_first(scratch_pool, dirents);
hi;
hi = apr_hash_next(hi))
{
@@ -683,7 +732,7 @@ remote_propget(apr_hash_t *props,
new_target_relative = svn_relpath_join(target_relative, this_name,
iterpool);
- SVN_ERR(remote_propget(props,
+ SVN_ERR(remote_propget(props, NULL,
propname,
target_prefix,
new_target_relative,
@@ -691,7 +740,7 @@ remote_propget(apr_hash_t *props,
revnum,
ra_session,
depth_below_here,
- perm_pool, iterpool));
+ result_pool, iterpool));
}
svn_pool_destroy(iterpool);
@@ -792,7 +841,8 @@ get_prop_from_wc(apr_hash_t **props,
/* Note: this implementation is very similar to svn_client_proplist. */
svn_error_t *
-svn_client_propget4(apr_hash_t **props,
+svn_client_propget5(apr_hash_t **props,
+ apr_array_header_t **inherited_props,
const char *propname,
const char *target,
const svn_opt_revision_t *peg_revision,
@@ -805,6 +855,8 @@ svn_client_propget4(apr_hash_t **props,
apr_pool_t *scratch_pool)
{
svn_revnum_t revnum;
+ svn_boolean_t local_explicit_props;
+ svn_boolean_t local_iprops;
SVN_ERR(error_if_wcprop_name(propname));
if (!svn_path_is_url(target))
@@ -814,9 +866,19 @@ svn_client_propget4(apr_hash_t **props,
target);
revision = svn_cl__rev_default_to_peg(revision, peg_revision);
- if (! svn_path_is_url(target)
- && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(peg_revision->kind)
- && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(revision->kind))
+ local_explicit_props =
+ (! svn_path_is_url(target)
+ && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(peg_revision->kind)
+ && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(revision->kind));
+
+ local_iprops =
+ (local_explicit_props
+ && (peg_revision->kind == svn_opt_revision_working
+ || peg_revision->kind == svn_opt_revision_unspecified )
+ && (revision->kind == svn_opt_revision_working
+ || revision->kind == svn_opt_revision_unspecified ));
+
+ if (local_explicit_props)
{
svn_node_kind_t kind;
svn_boolean_t pristine;
@@ -850,30 +912,120 @@ svn_client_propget4(apr_hash_t **props,
else if (err)
return svn_error_trace(err);
+ if (inherited_props && local_iprops)
+ SVN_ERR(svn_wc__get_iprops(inherited_props, ctx->wc_ctx,
+ target, propname,
+ scratch_pool, scratch_pool));
+
SVN_ERR(get_prop_from_wc(props, propname, target,
pristine, kind,
depth, changelists, ctx, scratch_pool,
result_pool));
}
- else
+
+ if ((inherited_props && !local_iprops)
+ || !local_explicit_props)
{
- svn_client__pathrev_t *loc;
svn_ra_session_t *ra_session;
svn_node_kind_t kind;
+ svn_opt_revision_t new_operative_rev;
+ svn_opt_revision_t new_peg_rev;
+
+ /* Peg or operative revisions may be WC specific for
+ TARGET's explicit props, but still require us to
+ contact the repository for the inherited properties. */
+ if (SVN_CLIENT__REVKIND_NEEDS_WC(peg_revision->kind)
+ || SVN_CLIENT__REVKIND_NEEDS_WC(revision->kind))
+ {
+ svn_revnum_t origin_rev;
+ const char *repos_relpath;
+ const char *repos_root_url;
+ const char *repos_uuid;
+ const char *local_abspath;
+ const char *copy_root_abspath;
+ svn_boolean_t is_copy;
+
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath, target,
+ scratch_pool));
+
+ if (SVN_CLIENT__REVKIND_NEEDS_WC(peg_revision->kind))
+ {
+ SVN_ERR(svn_wc__node_get_origin(&is_copy,
+ &origin_rev,
+ &repos_relpath,
+ &repos_root_url,
+ &repos_uuid,
+ ©_root_abspath,
+ ctx->wc_ctx,
+ local_abspath,
+ FALSE, /* scan_deleted */
+ result_pool,
+ scratch_pool));
+ if (repos_relpath)
+ {
+ target = svn_path_url_add_component2(repos_root_url,
+ repos_relpath,
+ scratch_pool);
+ if (SVN_CLIENT__REVKIND_NEEDS_WC(peg_revision->kind))
+ {
+ svn_revnum_t resolved_peg_rev;
+
+ SVN_ERR(svn_client__get_revision_number(
+ &resolved_peg_rev, NULL, ctx->wc_ctx,
+ local_abspath, NULL, peg_revision, scratch_pool));
+ new_peg_rev.kind = svn_opt_revision_number;
+ new_peg_rev.value.number = resolved_peg_rev;
+ peg_revision = &new_peg_rev;
+ }
+
+ if (SVN_CLIENT__REVKIND_NEEDS_WC(revision->kind))
+ {
+ svn_revnum_t resolved_operative_rev;
+
+ SVN_ERR(svn_client__get_revision_number(
+ &resolved_operative_rev, NULL, ctx->wc_ctx,
+ local_abspath, NULL, revision, scratch_pool));
+ new_operative_rev.kind = svn_opt_revision_number;
+ new_operative_rev.value.number = resolved_operative_rev;
+ revision = &new_operative_rev;
+ }
+ }
+ else
+ {
+ /* TARGET doesn't exist in the repository, so there are
+ obviously not inherited props to be found there. */
+ local_iprops = TRUE;
+ *inherited_props = apr_array_make(
+ result_pool, 0, sizeof(svn_prop_inherited_item_t *));
+ }
+ }
+ }
+
+ /* Do we still have anything to ask the repository about? */
+ if (!local_explicit_props || !local_iprops)
+ {
+ svn_client__pathrev_t *loc;
- /* Get an RA plugin for this filesystem object. */
- SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &loc,
- target, NULL,
- peg_revision,
- revision, ctx, scratch_pool));
-
- SVN_ERR(svn_ra_check_path(ra_session, "", loc->rev, &kind, scratch_pool));
-
- *props = apr_hash_make(result_pool);
- SVN_ERR(remote_propget(*props, propname, loc->url, "",
- kind, loc->rev, ra_session,
- depth, result_pool, scratch_pool));
- revnum = loc->rev;
+ /* Get an RA plugin for this filesystem object. */
+ SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &loc,
+ target, NULL,
+ peg_revision,
+ revision, ctx,
+ scratch_pool));
+
+ SVN_ERR(svn_ra_check_path(ra_session, "", loc->rev, &kind,
+ scratch_pool));
+
+ if (!local_explicit_props)
+ *props = apr_hash_make(result_pool);
+
+ SVN_ERR(remote_propget(!local_explicit_props ? *props : NULL,
+ !local_iprops ? inherited_props : NULL,
+ propname, loc->url, "",
+ kind, loc->rev, ra_session,
+ depth, result_pool, scratch_pool));
+ revnum = loc->rev;
+ }
}
if (actual_revnum)
@@ -907,19 +1059,24 @@ svn_client_revprop_get(const char *propn
}
-/* Call RECEIVER for the given PATH and PROP_HASH.
+/* Call RECEIVER for the given PATH and its PROP_HASH and/or
+ * INHERITED_PROPERTIES.
*
- * If PROP_HASH is null or has zero count, do nothing.
+ * If PROP_HASH is null or has zero count or INHERITED_PROPERTIES is null,
+ * then do nothing.
*/
static svn_error_t*
call_receiver(const char *path,
apr_hash_t *prop_hash,
- svn_proplist_receiver_t receiver,
+ apr_array_header_t *inherited_properties,
+ svn_proplist_receiver2_t receiver,
void *receiver_baton,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
- if (prop_hash && apr_hash_count(prop_hash))
- SVN_ERR(receiver(receiver_baton, path, prop_hash, pool));
+ if ((prop_hash && apr_hash_count(prop_hash))
+ || inherited_properties)
+ SVN_ERR(receiver(receiver_baton, path, prop_hash, inherited_properties,
+ scratch_pool));
return SVN_NO_ERROR;
}
@@ -927,20 +1084,23 @@ call_receiver(const char *path,
/* 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.
+ * If GET_EXPLICIT_PROPS is true, then call RECEIVER for paths at or under
+ * "TARGET_PREFIX/TARGET_RELATIVE@REVNUM" (obtained using RA_SESSION) which
+ * have regular properties. If GET_TARGET_INHERITED_PROPS is true, then send
+ * the target's inherited properties to the callback.
*
- * Allocate the new item and its contents in POOL.
- * Do all looping, recursion, and temporary work in SCRATCHPOOL.
+ * The 'path' and keys for 'prop_hash' and 'inherited_prop' arguments to
+ * RECEIVER are all URLs.
+ *
+ * RESULT_POOL is used to allocated the 'path', 'prop_hash', and
+ * 'inherited_prop' arguments to RECEIVER. SCRATCH_POOL is used for all
+ * other (temporary) allocations.
*
* KIND is the kind of the node at "TARGET_PREFIX/TARGET_RELATIVE".
*
* If the target is a directory, only fetch properties for the files
- * and directories at depth DEPTH.
+ * and directories at depth DEPTH. DEPTH has not effect on inherited
+ * properties.
*/
static svn_error_t *
remote_proplist(const char *target_prefix,
@@ -948,29 +1108,36 @@ remote_proplist(const char *target_prefi
svn_node_kind_t kind,
svn_revnum_t revnum,
svn_ra_session_t *ra_session,
+ svn_boolean_t get_explicit_props,
+ svn_boolean_t get_target_inherited_props,
svn_depth_t depth,
- svn_proplist_receiver_t receiver,
+ svn_proplist_receiver2_t receiver,
void *receiver_baton,
- apr_pool_t *pool,
- apr_pool_t *scratchpool)
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
apr_hash_t *dirents;
- apr_hash_t *prop_hash, *final_hash;
+ apr_hash_t *prop_hash = NULL;
+ apr_hash_t *final_hash = NULL;
apr_hash_index_t *hi;
const char *target_full_url =
- svn_path_url_add_component2(target_prefix, target_relative, scratchpool);
+ svn_path_url_add_component2(target_prefix, target_relative, scratch_pool);
+ apr_array_header_t *inherited_props;
+ /* Note that we pass only the SCRATCH_POOL to svn_ra_get[dir*|file*] because
+ we'll be filtering out non-regular properties from PROP_HASH before we
+ return. */
if (kind == svn_node_dir)
{
SVN_ERR(svn_ra_get_dir2(ra_session,
(depth > svn_depth_empty) ? &dirents : NULL,
NULL, &prop_hash, target_relative, revnum,
- SVN_DIRENT_KIND, scratchpool));
+ SVN_DIRENT_KIND, scratch_pool));
}
else if (kind == svn_node_file)
{
SVN_ERR(svn_ra_get_file(ra_session, target_relative, revnum,
- NULL, NULL, &prop_hash, scratchpool));
+ NULL, NULL, &prop_hash, scratch_pool));
}
else
{
@@ -979,38 +1146,50 @@ remote_proplist(const char *target_prefi
target_full_url);
}
- /* 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 char *name = svn__apr_hash_index_key(hi);
- apr_ssize_t klen = svn__apr_hash_index_klen(hi);
- svn_string_t *value = svn__apr_hash_index_val(hi);
- svn_prop_kind_t prop_kind;
-
- prop_kind = svn_property_kind2(name);
+ if (get_target_inherited_props)
+ SVN_ERR(svn_ra_get_inherited_props(ra_session, &inherited_props,
+ target_relative, revnum,
+ result_pool, scratch_pool));
+ else
+ inherited_props = NULL;
- if (prop_kind == svn_prop_regular_kind)
+ if (get_explicit_props)
+ {
+ /* Filter out non-regular properties, since the RA layer returns all
+ kinds. Copy regular properties keys/vals from the prop_hash
+ allocated in SCRATCH_POOL to the "final" hash allocated in
+ RESULT_POOL. */
+ final_hash = apr_hash_make(result_pool);
+ for (hi = apr_hash_first(scratch_pool, prop_hash);
+ hi;
+ hi = apr_hash_next(hi))
{
- name = apr_pstrdup(pool, name);
- value = svn_string_dup(value, pool);
- apr_hash_set(final_hash, name, klen, value);
- }
+ const char *name = svn__apr_hash_index_key(hi);
+ apr_ssize_t klen = svn__apr_hash_index_klen(hi);
+ svn_string_t *value = svn__apr_hash_index_val(hi);
+ svn_prop_kind_t prop_kind;
+
+ prop_kind = svn_property_kind2(name);
+
+ if (prop_kind == svn_prop_regular_kind)
+ {
+ name = apr_pstrdup(result_pool, name);
+ value = svn_string_dup(value, result_pool);
+ apr_hash_set(final_hash, name, klen, value);
+ }
+ }
}
- SVN_ERR(call_receiver(target_full_url, final_hash, receiver, receiver_baton,
- pool));
+ SVN_ERR(call_receiver(target_full_url, final_hash, inherited_props,
+ receiver, receiver_baton, result_pool));
if (depth > svn_depth_empty
+ && get_explicit_props
&& (kind == svn_node_dir) && (apr_hash_count(dirents) > 0))
{
- apr_pool_t *subpool = svn_pool_create(scratchpool);
+ apr_pool_t *subpool = svn_pool_create(scratch_pool);
- for (hi = apr_hash_first(scratchpool, dirents);
+ for (hi = apr_hash_first(scratch_pool, dirents);
hi;
hi = apr_hash_next(hi))
{
@@ -1036,10 +1215,12 @@ remote_proplist(const char *target_prefi
this_ent->kind,
revnum,
ra_session,
+ TRUE,
+ FALSE,
depth_below_here,
receiver,
receiver_baton,
- pool,
+ result_pool,
subpool));
}
}
@@ -1055,7 +1236,7 @@ remote_proplist(const char *target_prefi
struct recursive_proplist_receiver_baton
{
svn_wc_context_t *wc_ctx; /* Working copy context. */
- svn_proplist_receiver_t wrapped_receiver; /* Proplist receiver to call. */
+ svn_proplist_receiver2_t wrapped_receiver; /* Proplist receiver to call. */
void *wrapped_receiver_baton; /* Baton for the proplist receiver. */
/* Anchor, anchor_abspath pair for converting to relative paths */
@@ -1086,114 +1267,275 @@ recursive_proplist_receiver(void *baton,
path = local_abspath;
return svn_error_trace(b->wrapped_receiver(b->wrapped_receiver_baton,
- path, props, scratch_pool));
+ path, props, NULL,
+ scratch_pool));
}
-svn_error_t *
-svn_client_proplist3(const char *path_or_url,
- const svn_opt_revision_t *peg_revision,
- const svn_opt_revision_t *revision,
- svn_depth_t depth,
- const apr_array_header_t *changelists,
- svn_proplist_receiver_t receiver,
- void *receiver_baton,
- svn_client_ctx_t *ctx,
- apr_pool_t *pool)
+/* Helper for svn_client_proplist4 when retrieving properties and/or
+ inherited properties from the repository. Except as noted below,
+ all arguments are as per svn_client_proplist4.
+
+ GET_EXPLICIT_PROPS controls if explicit props are retrieved. */
+static svn_error_t *
+get_remote_props(const char *path_or_url,
+ const svn_opt_revision_t *peg_revision,
+ const svn_opt_revision_t *revision,
+ svn_depth_t depth,
+ svn_boolean_t get_explicit_props,
+ svn_boolean_t get_target_inherited_props,
+ svn_proplist_receiver2_t receiver,
+ void *receiver_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
- peg_revision = svn_cl__rev_default_to_head_or_working(peg_revision,
- path_or_url);
- revision = svn_cl__rev_default_to_peg(revision, peg_revision);
+ svn_ra_session_t *ra_session;
+ svn_node_kind_t kind;
+ svn_opt_revision_t new_operative_rev;
+ svn_opt_revision_t new_peg_rev;
+ svn_client__pathrev_t *loc;
+
+ /* Peg or operative revisions may be WC specific for
+ PATH_OR_URL's explicit props, but still require us to
+ contact the repository for the inherited properties. */
+ if (SVN_CLIENT__REVKIND_NEEDS_WC(peg_revision->kind)
+ || SVN_CLIENT__REVKIND_NEEDS_WC(revision->kind))
+ {
+ svn_revnum_t origin_rev;
+ const char *repos_relpath;
+ const char *repos_root_url;
+ const char *repos_uuid;
+ const char *local_abspath;
+ const char *copy_root_abspath;
+ svn_boolean_t is_copy;
- if (depth == svn_depth_unknown)
- depth = svn_depth_empty;
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath, path_or_url,
+ scratch_pool));
- if (! svn_path_is_url(path_or_url)
- && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(peg_revision->kind)
- && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(revision->kind))
- {
- svn_boolean_t pristine;
- svn_node_kind_t kind;
- apr_hash_t *changelist_hash = NULL;
- const char *local_abspath;
+ if (SVN_CLIENT__REVKIND_NEEDS_WC(peg_revision->kind))
+ {
+ SVN_ERR(svn_wc__node_get_origin(&is_copy,
+ &origin_rev,
+ &repos_relpath,
+ &repos_root_url,
+ &repos_uuid,
+ ©_root_abspath,
+ ctx->wc_ctx,
+ local_abspath,
+ FALSE, /* scan_deleted */
+ result_pool,
+ scratch_pool));
+ if (repos_relpath)
+ {
+ path_or_url =
+ svn_path_url_add_component2(repos_root_url,
+ repos_relpath,
+ scratch_pool);
+ if (SVN_CLIENT__REVKIND_NEEDS_WC(peg_revision->kind))
+ {
+ svn_revnum_t resolved_peg_rev;
+
+ SVN_ERR(svn_client__get_revision_number(&resolved_peg_rev,
+ NULL, ctx->wc_ctx,
+ local_abspath, NULL,
+ peg_revision,
+ scratch_pool));
+ new_peg_rev.kind = svn_opt_revision_number;
+ new_peg_rev.value.number = resolved_peg_rev;
+ peg_revision = &new_peg_rev;
+ }
+
+ if (SVN_CLIENT__REVKIND_NEEDS_WC(revision->kind))
+ {
+ svn_revnum_t resolved_operative_rev;
+
+ SVN_ERR(svn_client__get_revision_number(
+ &resolved_operative_rev,
+ NULL, ctx->wc_ctx,
+ local_abspath, NULL,
+ revision,
+ scratch_pool));
+ new_operative_rev.kind = svn_opt_revision_number;
+ new_operative_rev.value.number = resolved_operative_rev;
+ revision = &new_operative_rev;
+ }
+ }
+ else
+ {
+ /* PATH_OR_URL doesn't exist in the repository, so there are
+ obviously not inherited props to be found there. If we
+ aren't looking for explicit props then we're done. */
+ if (!get_explicit_props)
+ return SVN_NO_ERROR;
+ }
+ }
+ }
- SVN_ERR(svn_dirent_get_absolute(&local_abspath, path_or_url, pool));
+ /* Get an RA session for this URL. */
+ SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &loc,
+ path_or_url, NULL,
+ peg_revision,
+ revision, ctx,
+ result_pool));
+
+ SVN_ERR(svn_ra_check_path(ra_session, "", loc->rev, &kind,
+ result_pool));
+
+ SVN_ERR(remote_proplist(loc->url, "", kind, loc->rev, ra_session,
+ get_explicit_props,
+ get_target_inherited_props,
+ depth, receiver, receiver_baton,
+ result_pool, scratch_pool));
+ return SVN_NO_ERROR;
+}
- pristine = ((revision->kind == svn_opt_revision_committed)
- || (revision->kind == svn_opt_revision_base));
+/* Helper for svn_client_proplist4 when retrieving properties and
+ possibly inherited properties from the WC. All arguments are as
+ per svn_client_proplist4. */
+static svn_error_t *
+get_local_props(const char *path_or_url,
+ const svn_opt_revision_t *revision,
+ svn_depth_t depth,
+ const apr_array_header_t *changelists,
+ svn_boolean_t get_target_inherited_props,
+ svn_proplist_receiver2_t receiver,
+ void *receiver_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_boolean_t pristine;
+ svn_node_kind_t kind;
+ apr_hash_t *changelist_hash = NULL;
+ const char *local_abspath;
- SVN_ERR(svn_wc_read_kind(&kind, ctx->wc_ctx, local_abspath, FALSE,
- pool));
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath, path_or_url,
+ scratch_pool));
- if (kind == svn_node_unknown || kind == svn_node_none)
- {
- /* svn uses SVN_ERR_UNVERSIONED_RESOURCE as warning only
- for this function. */
- return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL,
- _("'%s' is not under version control"),
- svn_dirent_local_style(local_abspath,
- pool));
- }
+ pristine = ((revision->kind == svn_opt_revision_committed)
+ || (revision->kind == svn_opt_revision_base));
- if (changelists && changelists->nelts)
- SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash,
- changelists, pool));
+ SVN_ERR(svn_wc_read_kind(&kind, ctx->wc_ctx, local_abspath, FALSE,
+ scratch_pool));
- /* Fetch, recursively or not. */
- if (kind == svn_node_dir)
- {
- struct recursive_proplist_receiver_baton rb;
+ if (kind == svn_node_unknown || kind == svn_node_none)
+ {
+ /* svn uses SVN_ERR_UNVERSIONED_RESOURCE as warning only
+ for this function. */
+ return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL,
+ _("'%s' is not under version control"),
+ svn_dirent_local_style(local_abspath,
+ scratch_pool));
+ }
- rb.wc_ctx = ctx->wc_ctx;
- rb.wrapped_receiver = receiver;
- rb.wrapped_receiver_baton = receiver_baton;
+ if (get_target_inherited_props)
+ {
+ apr_array_header_t *iprops;
- if (strcmp(path_or_url, local_abspath) != 0)
- {
- rb.anchor = path_or_url;
- rb.anchor_abspath = local_abspath;
- }
- else
- {
- rb.anchor = NULL;
- rb.anchor_abspath = NULL;
- }
+ SVN_ERR(svn_wc__get_iprops(&iprops, ctx->wc_ctx, local_abspath,
+ NULL, scratch_pool, scratch_pool));
+ SVN_ERR(call_receiver(path_or_url, NULL, iprops, receiver,
+ receiver_baton, scratch_pool));
+ }
+
+ if (changelists && changelists->nelts)
+ SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash,
+ changelists, scratch_pool));
- SVN_ERR(svn_wc__prop_list_recursive(ctx->wc_ctx, local_abspath, NULL,
- depth, pristine, changelists,
- recursive_proplist_receiver, &rb,
- ctx->cancel_func,
- ctx->cancel_baton, pool));
+ /* Fetch, recursively or not. */
+ if (kind == svn_node_dir)
+ {
+ struct recursive_proplist_receiver_baton rb;
+
+ rb.wc_ctx = ctx->wc_ctx;
+ rb.wrapped_receiver = receiver;
+ rb.wrapped_receiver_baton = receiver_baton;
+
+ if (strcmp(path_or_url, local_abspath) != 0)
+ {
+ rb.anchor = path_or_url;
+ rb.anchor_abspath = local_abspath;
}
- else if (svn_wc__changelist_match(ctx->wc_ctx, local_abspath,
- changelist_hash, pool))
+ else
{
- apr_hash_t *hash;
+ rb.anchor = NULL;
+ rb.anchor_abspath = NULL;
+ }
- SVN_ERR(pristine_or_working_props(&hash, ctx->wc_ctx, local_abspath,
- pristine, pool, pool));
- SVN_ERR(call_receiver(path_or_url, hash,
- receiver, receiver_baton, pool));
+ SVN_ERR(svn_wc__prop_list_recursive(ctx->wc_ctx, local_abspath, NULL,
+ depth, pristine, changelists,
+ recursive_proplist_receiver, &rb,
+ ctx->cancel_func,
+ ctx->cancel_baton, result_pool));
+ }
+ else if (svn_wc__changelist_match(ctx->wc_ctx, local_abspath,
+ changelist_hash, scratch_pool))
+ {
+ apr_hash_t *hash;
+
+ SVN_ERR(pristine_or_working_props(&hash, ctx->wc_ctx, local_abspath,
+ pristine, result_pool,
+ scratch_pool));
+ SVN_ERR(call_receiver(path_or_url, hash, NULL,
+ receiver, receiver_baton, scratch_pool));
- }
}
- else /* remote target */
- {
- svn_ra_session_t *ra_session;
- svn_node_kind_t kind;
- apr_pool_t *subpool = svn_pool_create(pool);
- svn_client__pathrev_t *loc;
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_proplist4(const char *path_or_url,
+ const svn_opt_revision_t *peg_revision,
+ const svn_opt_revision_t *revision,
+ svn_depth_t depth,
+ const apr_array_header_t *changelists,
+ svn_boolean_t get_target_inherited_props,
+ svn_proplist_receiver2_t receiver,
+ void *receiver_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_boolean_t local_explicit_props;
+ svn_boolean_t local_iprops;
+
+ peg_revision = svn_cl__rev_default_to_head_or_working(peg_revision,
+ path_or_url);
+ revision = svn_cl__rev_default_to_peg(revision, peg_revision);
- /* Get an RA session for this URL. */
- SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &loc,
- path_or_url, NULL,
- peg_revision,
- revision, ctx, pool));
+ if (depth == svn_depth_unknown)
+ depth = svn_depth_empty;
- SVN_ERR(svn_ra_check_path(ra_session, "", loc->rev, &kind, pool));
+ /* Are explicit props available locally? */
+ local_explicit_props =
+ (! svn_path_is_url(path_or_url)
+ && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(peg_revision->kind)
+ && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(revision->kind));
+
+ /* If we want iprops are they avaiable locally? */
+ local_iprops =
+ (get_target_inherited_props /* We want iprops */
+ && local_explicit_props /* No local explicit props means no local iprops. */
+ && (peg_revision->kind == svn_opt_revision_working
+ || peg_revision->kind == svn_opt_revision_unspecified )
+ && (revision->kind == svn_opt_revision_working
+ || revision->kind == svn_opt_revision_unspecified ));
+
+ if ((get_target_inherited_props && !local_iprops)
+ || !local_explicit_props)
+ {
+ SVN_ERR(get_remote_props(path_or_url, peg_revision, revision, depth,
+ !local_explicit_props,
+ (get_target_inherited_props && !local_iprops),
+ receiver, receiver_baton, ctx, result_pool,
+ scratch_pool));
+ }
- SVN_ERR(remote_proplist(loc->url, "", kind, loc->rev, ra_session, depth,
- receiver, receiver_baton, pool, subpool));
- svn_pool_destroy(subpool);
+ if (local_explicit_props)
+ {
+ SVN_ERR(get_local_props(path_or_url, revision, depth, changelists,
+ local_iprops, receiver, receiver_baton, ctx,
+ result_pool, scratch_pool));
}
return SVN_NO_ERROR;
Modified: subversion/branches/compressed-pristines/subversion/libsvn_client/repos_diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_client/repos_diff.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_client/repos_diff.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_client/repos_diff.c Sat Nov 24 20:29:11 2012
@@ -1151,6 +1151,13 @@ close_directory(void *dir_baton,
const char *deleted_path = svn__apr_hash_index_key(hi);
deleted_path_notify_t *dpn = svn__apr_hash_index_val(hi);
+ /* Ignore paths which are not children of b->path. (There
+ should be none due to editor ordering constraints, but
+ ra_serf drops the ball here -- see issue #3802 for
+ details.) */
+ if (! svn_relpath_skip_ancestor(b->path, deleted_path))
+ continue;
+
notify = svn_wc_create_notify(deleted_path, dpn->action, pool);
notify->kind = dpn->kind;
notify->content_state = notify->prop_state = dpn->state;
Modified: subversion/branches/compressed-pristines/subversion/libsvn_client/revisions.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_client/revisions.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_client/revisions.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_client/revisions.c Sat Nov 24 20:29:11 2012
@@ -96,7 +96,7 @@ svn_client__get_revision_number(svn_revn
scratch_pool, scratch_pool);
/* Return the same error as older code did (before and at r935091).
- At least svn_client_proplist3 promises SVN_ERR_ENTRY_NOT_FOUND. */
+ At least svn_client_proplist4 promises SVN_ERR_ENTRY_NOT_FOUND. */
if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
{
svn_error_clear(err);
Modified: subversion/branches/compressed-pristines/subversion/libsvn_client/switch.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_client/switch.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_client/switch.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_client/switch.c Sat Nov 24 20:29:11 2012
@@ -79,6 +79,8 @@ switch_internal(svn_revnum_t *result_rev
svn_revnum_t revnum;
svn_error_t *err = SVN_NO_ERROR;
const char *diff3_cmd;
+ apr_hash_t *wcroot_iprops;
+ apr_array_header_t *inherited_props;
svn_boolean_t use_commit_times;
svn_boolean_t sleep_here = FALSE;
svn_boolean_t *use_sleep = timestamp_sleep ? timestamp_sleep : &sleep_here;
@@ -218,6 +220,62 @@ switch_internal(svn_revnum_t *result_rev
svn_dirent_dirname(local_abspath, pool));
}
+ wcroot_iprops = apr_hash_make(pool);
+
+ /* Will the base of LOCAL_ABSPATH require an iprop cache post-switch?
+ If we are switching LOCAL_ABSPATH to the root of the repository then
+ we don't need to cache inherited properties. In all other cases we
+ *might* need to cache iprops. */
+ if (strcmp(switch_loc->repos_root_url, switch_loc->url) != 0)
+ {
+ svn_boolean_t wc_root;
+ svn_boolean_t needs_iprop_cache = TRUE;
+
+ SVN_ERR(svn_wc__strictly_is_wc_root(&wc_root,
+ ctx->wc_ctx,
+ local_abspath,
+ pool));
+
+ /* Switching the WC root to anything but the repos root means
+ we need an iprop cache. */
+ if (!wc_root)
+ {
+ /* We know we are switching a subtree to something other than the
+ repos root, but if we are unswitching that subtree we don't
+ need an iprops cache. */
+ const char *target_parent_url;
+ const char *unswitched_url;
+
+ /* Calculate the URL LOCAL_ABSPATH would have if it was unswitched
+ relative to its parent. */
+ SVN_ERR(svn_wc__node_get_url(&target_parent_url, ctx->wc_ctx,
+ svn_dirent_dirname(local_abspath,
+ pool),
+ pool, pool));
+ unswitched_url = svn_path_url_add_component2(
+ target_parent_url,
+ svn_dirent_basename(local_abspath, pool),
+ pool);
+
+ /* If LOCAL_ABSPATH will be unswitched relative to its parent, then
+ it doesn't need an iprop cache. Note: It doesn't matter if
+ LOCAL_ABSPATH is withing a switched subtree, only if it's the
+ *root* of a switched subtree.*/
+ if (strcmp(unswitched_url, switch_loc->url) == 0)
+ needs_iprop_cache = FALSE;
+ }
+
+
+ if (needs_iprop_cache)
+ {
+ SVN_ERR(svn_ra_get_inherited_props(ra_session, &inherited_props,
+ "", switch_loc->rev, pool,
+ pool));
+ apr_hash_set(wcroot_iprops, local_abspath, APR_HASH_KEY_STRING,
+ inherited_props);
+ }
+ }
+
SVN_ERR(svn_ra_reparent(ra_session, anchor_url, pool));
/* Fetch the switch (update) editor. If REVISION is invalid, that's
@@ -231,8 +289,8 @@ switch_internal(svn_revnum_t *result_rev
SVN_ERR(svn_wc__get_switch_editor(&switch_editor, &switch_edit_baton,
&revnum, ctx->wc_ctx, anchor_abspath,
- target, switch_loc->url, use_commit_times,
- depth,
+ target, switch_loc->url, wcroot_iprops,
+ use_commit_times, depth,
depth_is_sticky, allow_unver_obstructions,
server_supports_depth,
diff3_cmd, preserved_exts,
Modified: subversion/branches/compressed-pristines/subversion/libsvn_client/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_client/update.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_client/update.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_client/update.c Sat Nov 24 20:29:11 2012
@@ -201,6 +201,8 @@ update_internal(svn_revnum_t *result_rev
svn_boolean_t *use_sleep = timestamp_sleep ? timestamp_sleep : &sleep_here;
svn_boolean_t clean_checkout = FALSE;
const char *diff3_cmd;
+ apr_hash_t *wcroot_iprops;
+ svn_opt_revision_t opt_rev;
svn_ra_session_t *ra_session;
const char *preserved_exts_str;
apr_array_header_t *preserved_exts;
@@ -211,6 +213,9 @@ update_internal(svn_revnum_t *result_rev
SVN_CONFIG_CATEGORY_CONFIG,
APR_HASH_KEY_STRING) : NULL;
+ if (result_rev)
+ *result_rev = SVN_INVALID_REVNUM;
+
/* An unknown depth can't be sticky. */
if (depth == svn_depth_unknown)
depth_is_sticky = FALSE;
@@ -350,10 +355,18 @@ update_internal(svn_revnum_t *result_rev
anchor_loc->url = corrected_url;
}
+ /* Resolve unspecified REVISION now, because we need to retrieve the
+ correct inherited props prior to the editor drive and we need to
+ use the same value of HEAD for both. */
+ opt_rev.kind = revision->kind;
+ opt_rev.value = revision->value;
+ if (opt_rev.kind == svn_opt_revision_unspecified)
+ opt_rev.kind = svn_opt_revision_head;
+
/* ### todo: shouldn't svn_client__get_revision_number be able
to take a URL as easily as a local path? */
SVN_ERR(svn_client__get_revision_number(&revnum, NULL, ctx->wc_ctx,
- local_abspath, ra_session, revision,
+ local_abspath, ra_session, &opt_rev,
pool));
SVN_ERR(svn_ra_has_capability(ra_session, &server_supports_depth,
@@ -363,12 +376,31 @@ update_internal(svn_revnum_t *result_rev
dfb.target_revision = revnum;
dfb.anchor_url = anchor_loc->url;
+ err = svn_client__get_inheritable_props(&wcroot_iprops, local_abspath,
+ revnum, depth, ra_session, ctx,
+ pool, pool);
+
+ /* We might be trying to update to a non-existant path-rev. */
+ if (err)
+ {
+ if (err->apr_err == SVN_ERR_FS_NOT_FOUND)
+ {
+ svn_error_clear(err);
+ err = NULL;
+ }
+ else
+ {
+ return svn_error_trace(err);
+ }
+ }
+
/* Fetch the update editor. If REVISION is invalid, that's okay;
the RA driver will call editor->set_target_revision later on. */
SVN_ERR(svn_wc__get_update_editor(&update_editor, &update_edit_baton,
&revnum, ctx->wc_ctx, anchor_abspath,
- target, use_commit_times, depth,
- depth_is_sticky, allow_unver_obstructions,
+ target, wcroot_iprops, use_commit_times,
+ depth, depth_is_sticky,
+ allow_unver_obstructions,
adds_as_modification,
server_supports_depth,
clean_checkout,
Modified: subversion/branches/compressed-pristines/subversion/libsvn_delta/compat.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_delta/compat.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_delta/compat.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_delta/compat.c Sat Nov 24 20:29:11 2012
@@ -1637,9 +1637,12 @@ apply_change(void **dir_baton,
change->copyfrom_path,
scratch_pool);
else
- /* ### prefix with "/" ? */
copyfrom_url = change->copyfrom_path;
+ /* Make this an FS path by prepending "/" */
+ if (copyfrom_url[0] != '/')
+ copyfrom_url = apr_pstrcat(scratch_pool, "/", copyfrom_url, NULL);
+
copyfrom_rev = change->copyfrom_rev;
}
@@ -1722,27 +1725,8 @@ drive_changes(const struct editor_baton
/* Get a sorted list of Ev1-relative paths. */
paths = get_sorted_paths(eb->changes, eb->base_relpath, scratch_pool);
-
- /* We need to pass SVN_INVALID_REVNUM to the path_driver. It uses this
- revision whenever it opens directory batons. If we specified a "real"
- value, such as eb->root.base_revision, then it might use that for a
- subdirectory *incorrectly*.
-
- Specifically, log_tests 38 demonstrates that erroneous behavior when
- it attempts to open "/A" at revision 0 (not there, of course).
-
- All this said: passing SVN_INVALID_REVNUM to all of those
- open_directory() calls is not the best behavior either, but it does
- happen to magically work. (ugh)
-
- Thankfully, we're moving away from this skitchy behavior to Ev2.
-
- Final note: every other caller of svn_delta_path_driver() passes
- SVN_INVALID_REVNUM, so we can't be the only goofball.
-
- Note: dropping const on the callback_baton. */
SVN_ERR(svn_delta_path_driver2(eb->deditor, eb->dedit_baton, paths,
- apply_change, (void *)eb,
+ FALSE, apply_change, (void *)eb,
scratch_pool));
return SVN_NO_ERROR;
Modified: subversion/branches/compressed-pristines/subversion/libsvn_delta/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_delta/deprecated.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_delta/deprecated.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_delta/deprecated.c Sat Nov 24 20:29:11 2012
@@ -39,15 +39,10 @@ svn_delta_path_driver(const svn_delta_ed
void *callback_baton,
apr_pool_t *scratch_pool)
{
- apr_array_header_t *sorted;
-
/* REVISION is dropped on the floor. */
- /* Construct a copy of PATHS, then sort them in a depth-first order. */
- sorted = apr_array_copy(scratch_pool, paths);
- qsort(sorted->elts, sorted->nelts, sorted->elt_size, svn_sort_compare_paths);
-
- return svn_error_trace(svn_delta_path_driver2(editor, edit_baton, sorted,
+ return svn_error_trace(svn_delta_path_driver2(editor, edit_baton, paths,
+ TRUE,
callback_func, callback_baton,
scratch_pool));
}
Modified: subversion/branches/compressed-pristines/subversion/libsvn_delta/editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_delta/editor.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_delta/editor.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_delta/editor.c Sat Nov 24 20:29:11 2012
@@ -77,23 +77,23 @@ struct svn_editor_t
#define END_CALLBACK(editor) ((editor)->within_callback = FALSE)
/* Marker to indicate no further changes are allowed on this node. */
-static const int marker_done;
+static const int marker_done = 0;
#define MARKER_DONE (&marker_done)
/* Marker indicating that add_* may be called for this path, or that it
can be the destination of a copy or move. For copy/move, the path
will switch to MARKER_ALLOW_ALTER, to enable further tweaks. */
-static const int marker_allow_add;
+static const int marker_allow_add = 0;
#define MARKER_ALLOW_ADD (&marker_allow_add)
/* Marker indicating that alter_* may be called for this path. */
-static const int marker_allow_alter;
+static const int marker_allow_alter = 0;
#define MARKER_ALLOW_ALTER (&marker_allow_alter)
/* Just like MARKER_DONE, but also indicates that the node was created
via add_directory(). This allows us to verify that the CHILDREN param
was comprehensive. */
-static const int marker_added_dir;
+static const int marker_added_dir = 0;
#define MARKER_ADDED_DIR (&marker_added_dir)
#define MARK_FINISHED(editor) ((editor)->finished = TRUE)
Modified: subversion/branches/compressed-pristines/subversion/libsvn_delta/path_driver.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_delta/path_driver.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_delta/path_driver.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_delta/path_driver.c Sat Nov 24 20:29:11 2012
@@ -133,6 +133,7 @@ svn_error_t *
svn_delta_path_driver2(const svn_delta_editor_t *editor,
void *edit_baton,
const apr_array_header_t *paths,
+ svn_boolean_t sort_paths,
svn_delta_path_driver_cb_func_t callback_func,
void *callback_baton,
apr_pool_t *pool)
@@ -151,6 +152,16 @@ svn_delta_path_driver2(const svn_delta_e
subpool = svn_pool_create(pool);
iterpool = svn_pool_create(pool);
+
+ /* sort paths if necessary */
+ if (sort_paths && paths->nelts > 1)
+ {
+ apr_array_header_t *sorted = apr_array_copy(subpool, paths);
+ qsort(sorted->elts, sorted->nelts, sorted->elt_size,
+ svn_sort_compare_paths);
+ paths = sorted;
+ }
+
item = apr_pcalloc(subpool, sizeof(*item));
/* If the root of the edit is also a target path, we want to call
Modified: subversion/branches/compressed-pristines/subversion/libsvn_delta/svndiff.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_delta/svndiff.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_delta/svndiff.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_delta/svndiff.c Sat Nov 24 20:29:11 2012
@@ -186,18 +186,86 @@ zlib_encode(const char *data,
}
static svn_error_t *
+send_simple_insertion_window(svn_txdelta_window_t *window,
+ struct encoder_baton *eb)
+{
+ unsigned char headers[4 + 5 * MAX_ENCODED_INT_LEN + MAX_INSTRUCTION_LEN];
+ unsigned char ibuf[MAX_INSTRUCTION_LEN];
+ unsigned char *header_current;
+ apr_size_t header_len;
+ apr_size_t ip_len, i;
+ apr_size_t len = window->new_data->len;
+
+ /* there is only one target copy op. It must span the whole window */
+ assert(window->ops[0].action_code == svn_txdelta_new);
+ assert(window->ops[0].length == window->tview_len);
+ assert(window->ops[0].offset == 0);
+
+ /* write stream header if necessary */
+ if (eb->header_done == FALSE)
+ {
+ eb->header_done = TRUE;
+ headers[0] = 'S';
+ headers[1] = 'V';
+ headers[2] = 'N';
+ headers[3] = (unsigned char)eb->version;
+ header_current = headers + 4;
+ }
+ else
+ {
+ header_current = headers;
+ }
+
+ /* Encode the action code and length. */
+ if (window->tview_len >> 6 == 0)
+ {
+ ibuf[0] = (unsigned char)(window->tview_len + (0x2 << 6));
+ ip_len = 1;
+ }
+ else
+ {
+ ibuf[0] = (0x2 << 6);
+ ip_len = encode_int(ibuf + 1, window->tview_len) - ibuf;
+ }
+
+ /* encode the window header. */
+ header_current[0] = 0; /* source offset == 0 */
+ header_current[1] = 0; /* source length == 0 */
+ header_current = encode_int(header_current + 2, window->tview_len);
+ header_current[0] = (unsigned char)ip_len; /* 1 instruction */
+ header_current = encode_int(&header_current[1], len);
+
+ /* append instructions (1 to a handful of bytes) */
+ for (i = 0; i < ip_len; ++i)
+ header_current[i] = ibuf[i];
+
+ header_len = header_current - headers + ip_len;
+
+ /* Write out the window. */
+ SVN_ERR(svn_stream_write(eb->output, (const char *)headers, &header_len));
+ if (len)
+ SVN_ERR(svn_stream_write(eb->output, window->new_data->data, &len));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
window_handler(svn_txdelta_window_t *window, void *baton)
{
struct encoder_baton *eb = baton;
- apr_pool_t *pool = svn_pool_create(eb->pool);
- svn_stringbuf_t *instructions = svn_stringbuf_create_empty(pool);
- svn_stringbuf_t *i1 = svn_stringbuf_create_empty(pool);
- svn_stringbuf_t *header = svn_stringbuf_create_empty(pool);
+ apr_pool_t *pool;
+ svn_stringbuf_t *instructions;
+ svn_stringbuf_t *i1;
+ svn_stringbuf_t *header;
const svn_string_t *newdata;
unsigned char ibuf[MAX_INSTRUCTION_LEN], *ip;
const svn_txdelta_op_t *op;
apr_size_t len;
+ /* use specialized code if there is no source */
+ if (window && !window->src_ops && window->num_ops == 1 && !eb->version)
+ return svn_error_trace(send_simple_insertion_window(window, eb));
+
/* Make sure we write the header. */
if (eb->header_done == FALSE)
{
@@ -229,6 +297,12 @@ window_handler(svn_txdelta_window_t *win
return svn_stream_close(output);
}
+ /* create the necessary data buffers */
+ pool = svn_pool_create(eb->pool);
+ instructions = svn_stringbuf_create_empty(pool);
+ i1 = svn_stringbuf_create_empty(pool);
+ header = svn_stringbuf_create_empty(pool);
+
/* Encode the instructions. */
for (op = window->ops; op < window->ops + window->num_ops; op++)
{
@@ -450,7 +524,7 @@ decode_size(apr_size_t *val,
*/
static svn_error_t *
zlib_decode(const unsigned char *in, apr_size_t inLen, svn_stringbuf_t *out,
- apr_size_t limit, svn_boolean_t copyless_allowed)
+ apr_size_t limit)
{
apr_size_t len;
const unsigned char *oldplace = in;
@@ -469,22 +543,10 @@ zlib_decode(const unsigned char *in, apr
inLen -= (in - oldplace);
if (inLen == len)
{
- if (copyless_allowed)
- {
- /* "in" is no longer used but the memory remains allocated for
- * at least as long as "out" will be used by the caller.
- */
- out->data = (char *)in;
- out->len = len;
- out->blocksize = len; /* sic! */
- }
- else
- {
- svn_stringbuf_ensure(out, len);
- memcpy(out->data, in, len);
- out->data[len] = 0;
- out->len = len;
- }
+ svn_stringbuf_ensure(out, len);
+ memcpy(out->data, in, len);
+ out->data[len] = 0;
+ out->len = len;
return SVN_NO_ERROR;
}
@@ -661,9 +723,9 @@ decode_window(svn_txdelta_window_t *wind
/* these may in fact simply return references to insend */
SVN_ERR(zlib_decode(insend, newlen, ndout,
- SVN_DELTA_WINDOW_SIZE, TRUE));
+ SVN_DELTA_WINDOW_SIZE));
SVN_ERR(zlib_decode(data, insend - data, instout,
- MAX_INSTRUCTION_SECTION_LEN, TRUE));
+ MAX_INSTRUCTION_SECTION_LEN));
newlen = ndout->len;
data = (unsigned char *)instout->data;
@@ -1008,8 +1070,7 @@ svn__compress(svn_string_t *in,
svn_stringbuf_t *out,
int compression_level)
{
- return zlib_encode(in->data, in->len, out,
- compression_level);
+ return zlib_encode(in->data, in->len, out, compression_level);
}
svn_error_t *
@@ -1017,6 +1078,5 @@ svn__decompress(svn_string_t *in,
svn_stringbuf_t *out,
apr_size_t limit)
{
- return zlib_decode((const unsigned char*)in->data, in->len, out, limit,
- FALSE);
+ return zlib_decode((const unsigned char*)in->data, in->len, out, limit);
}
Modified: subversion/branches/compressed-pristines/subversion/libsvn_delta/text_delta.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_delta/text_delta.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_delta/text_delta.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_delta/text_delta.c Sat Nov 24 20:29:11 2012
@@ -998,3 +998,42 @@ svn_error_t *svn_txdelta_send_txstream(s
return SVN_NO_ERROR;
}
+
+svn_error_t *
+svn_txdelta_send_contents(const unsigned char *contents,
+ apr_size_t len,
+ svn_txdelta_window_handler_t handler,
+ void *handler_baton,
+ apr_pool_t *pool)
+{
+ svn_string_t new_data;
+ svn_txdelta_op_t op = { svn_txdelta_new, 0, 0 };
+ svn_txdelta_window_t window = { 0, 0, 0, 1, 0 };
+ window.ops = &op;
+ window.new_data = &new_data;
+
+ /* send CONTENT as a series of max-sized windows */
+ while (len > 0)
+ {
+ /* stuff next chunk into the window */
+ window.tview_len = len < SVN_DELTA_WINDOW_SIZE
+ ? len
+ : SVN_DELTA_WINDOW_SIZE;
+ op.length = window.tview_len;
+ new_data.len = window.tview_len;
+ new_data.data = (const char*)contents;
+
+ /* update remaining */
+ contents += window.tview_len;
+ len -= window.tview_len;
+
+ /* shove it at the handler */
+ SVN_ERR((*handler)(&window, handler_baton));
+ }
+
+ /* indicate end of stream */
+ SVN_ERR((*handler)(NULL, handler_baton));
+
+ return SVN_NO_ERROR;
+}
+
Modified: subversion/branches/compressed-pristines/subversion/libsvn_diff/diff_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_diff/diff_file.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_diff/diff_file.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_diff/diff_file.c Sat Nov 24 20:29:11 2012
@@ -340,30 +340,17 @@ is_one_at_eof(struct file_info file[], a
/* Quickly determine whether there is a eol char in CHUNK.
* (mainly copy-n-paste from eol.c#svn_eol__find_eol_start).
*/
-#if SVN_UNALIGNED_ACCESS_IS_OK
-#if APR_SIZEOF_VOIDP == 8
-# define LOWER_7BITS_SET 0x7f7f7f7f7f7f7f7f
-# define BIT_7_SET 0x8080808080808080
-# define R_MASK 0x0a0a0a0a0a0a0a0a
-# define N_MASK 0x0d0d0d0d0d0d0d0d
-#else
-# define LOWER_7BITS_SET 0x7f7f7f7f
-# define BIT_7_SET 0x80808080
-# define R_MASK 0x0a0a0a0a
-# define N_MASK 0x0d0d0d0d
-#endif
-#endif
#if SVN_UNALIGNED_ACCESS_IS_OK
static svn_boolean_t contains_eol(apr_uintptr_t chunk)
{
- apr_uintptr_t r_test = chunk ^ R_MASK;
- apr_uintptr_t n_test = chunk ^ N_MASK;
+ apr_uintptr_t r_test = chunk ^ SVN__R_MASK;
+ apr_uintptr_t n_test = chunk ^ SVN__N_MASK;
- r_test |= (r_test & LOWER_7BITS_SET) + LOWER_7BITS_SET;
- n_test |= (n_test & LOWER_7BITS_SET) + LOWER_7BITS_SET;
+ r_test |= (r_test & SVN__LOWER_7BITS_SET) + SVN__LOWER_7BITS_SET;
+ n_test |= (n_test & SVN__LOWER_7BITS_SET) + SVN__LOWER_7BITS_SET;
- return (r_test & n_test & BIT_7_SET) != BIT_7_SET;
+ return (r_test & n_test & SVN__BIT_7_SET) != SVN__BIT_7_SET;
}
#endif
Modified: subversion/branches/compressed-pristines/subversion/libsvn_diff/parse-diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_diff/parse-diff.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_diff/parse-diff.c Sat Nov 24 20:29:11 2012
@@ -595,7 +595,6 @@ parse_next_hunk(svn_diff_hunk_t **hunk,
original_end = hunk_text_end;
if (modified_end == 0)
modified_end = hunk_text_end;
- break;
}
SVN_ERR(svn_io_file_seek(apr_file, APR_SET, &pos, iterpool));
@@ -1284,8 +1283,7 @@ svn_diff_parse_next_patch(svn_patch_t **
/* Run the state machine. */
for (i = 0; i < (sizeof(transitions) / sizeof(transitions[0])); i++)
{
- if (line->len > strlen(transitions[i].expected_input)
- && starts_with(line->data, transitions[i].expected_input)
+ if (starts_with(line->data, transitions[i].expected_input)
&& state == transitions[i].required_state)
{
SVN_ERR(transitions[i].fn(&state, line->data, *patch,
@@ -1302,19 +1300,24 @@ svn_diff_parse_next_patch(svn_patch_t **
}
else if (state == state_git_tree_seen && line_after_tree_header_read)
{
- /* We have a valid diff header for a patch with only tree changes.
- * Rewind to the start of the line just read, so subsequent calls
- * to this function don't end up skipping the line -- it may
- * contain a patch. */
- SVN_ERR(svn_io_file_seek(patch_file->apr_file, APR_SET, &last_line,
- scratch_pool));
- break;
+ /* git patches can contain an index line after the file mode line */
+ if (!starts_with(line->data, "index "))
+ {
+ /* We have a valid diff header for a patch with only tree changes.
+ * Rewind to the start of the line just read, so subsequent calls
+ * to this function don't end up skipping the line -- it may
+ * contain a patch. */
+ SVN_ERR(svn_io_file_seek(patch_file->apr_file, APR_SET, &last_line,
+ scratch_pool));
+ break;
+ }
}
else if (state == state_git_tree_seen)
{
line_after_tree_header_read = TRUE;
}
- else if (! valid_header_line && state != state_start)
+ else if (! valid_header_line && state != state_start
+ && !starts_with(line->data, "index "))
{
/* We've encountered an invalid diff header.
*
Modified: subversion/branches/compressed-pristines/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_fs/fs-loader.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_fs/fs-loader.c Sat Nov 24 20:29:11 2012
@@ -601,7 +601,8 @@ svn_fs_pack(const char *path,
SVN_MUTEX__WITH_LOCK(common_pool_lock,
vtable->pack_fs(fs, path, notify_func, notify_baton,
- cancel_func, cancel_baton, pool));
+ cancel_func, cancel_baton, pool,
+ common_pool));
return SVN_NO_ERROR;
}
@@ -623,6 +624,17 @@ svn_fs_recover(const char *path,
pool));
}
+svn_error_t *
+svn_fs_freeze(svn_fs_t *fs,
+ svn_error_t *(*freeze_body)(void *baton, apr_pool_t *pool),
+ void *baton,
+ apr_pool_t *pool)
+{
+ SVN_ERR(fs->vtable->freeze(fs, freeze_body, baton, pool));
+
+ return SVN_NO_ERROR;
+}
+
/* --- Berkeley-specific functions --- */
@@ -1192,6 +1204,27 @@ svn_fs_file_contents(svn_stream_t **cont
}
svn_error_t *
+svn_fs_try_process_file_contents(svn_boolean_t *success,
+ svn_fs_root_t *root,
+ const char *path,
+ svn_fs_process_contents_func_t processor,
+ void* baton,
+ apr_pool_t *pool)
+{
+ /* if the FS doesn't implement this function, report a "failed" attempt */
+ if (root->vtable->try_process_file_contents == NULL)
+ {
+ *success = FALSE;
+ return SVN_NO_ERROR;
+ }
+
+ return svn_error_trace(root->vtable->try_process_file_contents(
+ success,
+ root, path,
+ processor, baton, pool));
+}
+
+svn_error_t *
svn_fs_make_file(svn_fs_root_t *root, const char *path, apr_pool_t *pool)
{
SVN_ERR(svn_fs__path_valid(path, pool));
Modified: subversion/branches/compressed-pristines/subversion/libsvn_fs/fs-loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_fs/fs-loader.h?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_fs/fs-loader.h (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_fs/fs-loader.h Sat Nov 24 20:29:11 2012
@@ -107,7 +107,7 @@ typedef struct fs_library_vtable_t
svn_error_t *(*pack_fs)(svn_fs_t *fs, const char *path,
svn_fs_pack_notify_t notify_func, void *notify_baton,
svn_cancel_func_t cancel_func, void *cancel_baton,
- apr_pool_t *pool);
+ apr_pool_t *pool, apr_pool_t *common_pool);
/* Provider-specific functions should go here, even if they could go
in an object vtable, so that they are all kept together. */
@@ -202,6 +202,9 @@ typedef struct fs_vtable_t
svn_fs_get_locks_callback_t get_locks_func,
void *get_locks_baton,
apr_pool_t *pool);
+ svn_error_t *(*freeze)(svn_fs_t *fs,
+ svn_error_t *(*freeze_body)(void *, apr_pool_t *),
+ void *baton, apr_pool_t *pool);
svn_error_t *(*bdb_set_errcall)(svn_fs_t *fs,
void (*handler)(const char *errpfx,
char *msg));
@@ -303,6 +306,12 @@ typedef struct root_vtable_t
svn_error_t *(*file_contents)(svn_stream_t **contents,
svn_fs_root_t *root, const char *path,
apr_pool_t *pool);
+ svn_error_t *(*try_process_file_contents)(svn_boolean_t *success,
+ svn_fs_root_t *target_root,
+ const char *target_path,
+ svn_fs_process_contents_func_t processor,
+ void* baton,
+ apr_pool_t *pool);
svn_error_t *(*make_file)(svn_fs_root_t *root, const char *path,
apr_pool_t *pool);
svn_error_t *(*apply_textdelta)(svn_txdelta_window_handler_t *contents_p,
Modified: subversion/branches/compressed-pristines/subversion/libsvn_fs_base/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_fs_base/fs.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_fs_base/fs.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_fs_base/fs.c Sat Nov 24 20:29:11 2012
@@ -471,6 +471,14 @@ bdb_write_config(svn_fs_t *fs)
return svn_io_file_close(dbconfig_file, fs->pool);
}
+static svn_error_t *
+base_bdb_freeze(svn_fs_t *fs,
+ svn_error_t *(*freeze_body)(void *, apr_pool_t *),
+ void *baton,
+ apr_pool_t *pool)
+{
+ SVN__NOT_IMPLEMENTED();
+}
/* Creating a new filesystem */
@@ -492,6 +500,7 @@ static fs_vtable_t fs_vtable = {
svn_fs_base__unlock,
svn_fs_base__get_lock,
svn_fs_base__get_locks,
+ base_bdb_freeze,
base_bdb_set_errcall,
};
@@ -911,7 +920,8 @@ base_bdb_pack(svn_fs_t *fs,
void *notify_baton,
svn_cancel_func_t cancel,
void *cancel_baton,
- apr_pool_t *pool)
+ apr_pool_t *pool,
+ apr_pool_t *common_pool)
{
/* Packing is currently a no op for BDB. */
return SVN_NO_ERROR;
Modified: subversion/branches/compressed-pristines/subversion/libsvn_fs_base/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_fs_base/tree.c?rev=1413258&r1=1413257&r2=1413258&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_fs_base/tree.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_fs_base/tree.c Sat Nov 24 20:29:11 2012
@@ -3676,7 +3676,7 @@ window_consumer(svn_txdelta_window_t *wi
SVN_ERR(svn_stream_write(tb->target_stream,
tb->target_string->data,
&len));
- svn_stringbuf_set(tb->target_string, "");
+ svn_stringbuf_setempty(tb->target_string);
}
/* Is the window NULL? If so, we're done. */
@@ -5387,6 +5387,7 @@ static root_vtable_t root_vtable = {
base_file_length,
base_file_checksum,
base_file_contents,
+ NULL,
base_make_file,
base_apply_textdelta,
base_apply_text,