summaryrefslogtreecommitdiff
path: root/subversion/libsvn_ra/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_ra/compat.c')
-rw-r--r--subversion/libsvn_ra/compat.c114
1 files changed, 97 insertions, 17 deletions
diff --git a/subversion/libsvn_ra/compat.c b/subversion/libsvn_ra/compat.c
index ec3ff9d..b16bbef 100644
--- a/subversion/libsvn_ra/compat.c
+++ b/subversion/libsvn_ra/compat.c
@@ -23,6 +23,7 @@
#include <apr_pools.h>
+#include "svn_hash.h"
#include "svn_error.h"
#include "svn_pools.h"
#include "svn_sorts.h"
@@ -91,7 +92,7 @@ prev_log_path(const char **prev_path_p,
if (changed_paths)
{
/* See if PATH was explicitly changed in this revision. */
- change = apr_hash_get(changed_paths, path, APR_HASH_KEY_STRING);
+ change = svn_hash_gets(changed_paths, path);
if (change)
{
/* If PATH was not newly added in this revision, then it may or may
@@ -141,7 +142,7 @@ prev_log_path(const char **prev_path_p,
svn_sort__item_t item = APR_ARRAY_IDX(paths,
i - 1, svn_sort__item_t);
const char *ch_path = item.key;
- int len = strlen(ch_path);
+ size_t len = strlen(ch_path);
/* See if our path is the child of this change path. If
not, keep looking. */
@@ -154,7 +155,7 @@ prev_log_path(const char **prev_path_p,
path, to the change's copyfrom path. Otherwise, this
change isn't really interesting to us, and our search
continues. */
- change = apr_hash_get(changed_paths, ch_path, len);
+ change = item.value;
if (change->copyfrom_path)
{
if (action_p)
@@ -630,7 +631,6 @@ fr_log_message_receiver(void *baton,
{
struct fr_log_message_baton *lmb = baton;
struct rev *rev;
- apr_hash_index_t *hi;
rev = apr_palloc(lmb->pool, sizeof(*rev));
rev->revision = log_entry->revision;
@@ -639,17 +639,7 @@ fr_log_message_receiver(void *baton,
lmb->eldest = rev;
/* Duplicate log_entry revprops into rev->props */
- rev->props = apr_hash_make(lmb->pool);
- for (hi = apr_hash_first(pool, log_entry->revprops); hi;
- hi = apr_hash_next(hi))
- {
- void *val;
- const void *key;
-
- apr_hash_this(hi, &key, NULL, &val);
- apr_hash_set(rev->props, apr_pstrdup(lmb->pool, key), APR_HASH_KEY_STRING,
- svn_string_dup(val, lmb->pool));
- }
+ rev->props = svn_prop_hash_dup(log_entry->revprops, lmb->pool);
return prev_log_path(&lmb->path, &lmb->action,
&lmb->copyrev, log_entry->changed_paths2,
@@ -757,8 +747,9 @@ svn_ra__file_revs_from_log(svn_ra_session_t *ra_session,
/* Compute and send delta if client asked for it. */
if (delta_handler)
{
- /* Get the content delta. */
- svn_txdelta(&delta_stream, last_stream, stream, lastpool);
+ /* Get the content delta. Don't calculate checksums as we don't
+ * use them. */
+ svn_txdelta2(&delta_stream, last_stream, stream, FALSE, lastpool);
/* And send. */
SVN_ERR(svn_txdelta_send_txstream(delta_stream, delta_handler,
@@ -870,3 +861,92 @@ svn_ra__get_deleted_rev_from_log(svn_ra_session_t *session,
*revision_deleted = log_path_deleted_baton.revision_deleted;
return SVN_NO_ERROR;
}
+
+
+svn_error_t *
+svn_ra__get_inherited_props_walk(svn_ra_session_t *session,
+ const char *path,
+ svn_revnum_t revision,
+ apr_array_header_t **inherited_props,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const char *repos_root_url;
+ const char *session_url;
+ const char *parent_url;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+ *inherited_props =
+ apr_array_make(result_pool, 1, sizeof(svn_prop_inherited_item_t *));
+
+ /* Walk to the root of the repository getting inherited
+ props for PATH. */
+ SVN_ERR(svn_ra_get_repos_root2(session, &repos_root_url, scratch_pool));
+ SVN_ERR(svn_ra_get_session_url(session, &session_url, scratch_pool));
+ parent_url = session_url;
+
+ while (strcmp(repos_root_url, parent_url))
+ {
+ apr_hash_index_t *hi;
+ apr_hash_t *parent_props;
+ apr_hash_t *final_hash = apr_hash_make(result_pool);
+ svn_error_t *err;
+
+ svn_pool_clear(iterpool);
+ parent_url = svn_uri_dirname(parent_url, scratch_pool);
+ SVN_ERR(svn_ra_reparent(session, parent_url, iterpool));
+ err = session->vtable->get_dir(session, NULL, NULL,
+ &parent_props, "",
+ revision, SVN_DIRENT_ALL,
+ iterpool);
+
+ /* If the user doesn't have read access to a parent path then
+ skip, but allow them to inherit from further up. */
+ if (err)
+ {
+ if ((err->apr_err == SVN_ERR_RA_NOT_AUTHORIZED)
+ || (err->apr_err == SVN_ERR_RA_DAV_FORBIDDEN))
+ {
+ svn_error_clear(err);
+ continue;
+ }
+ else
+ {
+ return svn_error_trace(err);
+ }
+ }
+
+ for (hi = apr_hash_first(scratch_pool, parent_props);
+ 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);
+
+ if (svn_property_kind2(name) == 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);
+ }
+ }
+
+ if (apr_hash_count(final_hash))
+ {
+ svn_prop_inherited_item_t *new_iprop =
+ apr_palloc(result_pool, sizeof(*new_iprop));
+ new_iprop->path_or_url = svn_uri_skip_ancestor(repos_root_url,
+ parent_url,
+ result_pool);
+ new_iprop->prop_hash = final_hash;
+ svn_sort__array_insert(&new_iprop, *inherited_props, 0);
+ }
+ }
+
+ /* Reparent session back to original URL. */
+ SVN_ERR(svn_ra_reparent(session, session_url, scratch_pool));
+
+ svn_pool_destroy(iterpool);
+ return SVN_NO_ERROR;
+}