You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2011/11/04 20:08:11 UTC
svn commit: r1197715 - /subversion/trunk/subversion/libsvn_delta/compat.c
Author: hwright
Date: Fri Nov 4 19:08:11 2011
New Revision: 1197715
URL: http://svn.apache.org/viewvc?rev=1197715&view=rev
Log:
A checkpoint commit for property handling in the Ev2 shims.
* subversion/libsvn_delta/compat.c
(operation): Include both prop mods and prop dels.
(editor_baton): Add a fetch props func/baton.
(props_diff_func): New no-op function.
(get_operation): Initialize prop mods / dels.
(build): Fetch the current props, so we can generate the appropriate
mods and dels.
(change_props): New.
(drive): When closing a file or directory, do any props changes needed first.
(editor_from_delta): Add props fetch func/baton, and initialize baton members.
(svn_editor__insert_shims): Add props fetch func/baton.
Modified:
subversion/trunk/subversion/libsvn_delta/compat.c
Modified: subversion/trunk/subversion/libsvn_delta/compat.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_delta/compat.c?rev=1197715&r1=1197714&r2=1197715&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_delta/compat.c (original)
+++ subversion/trunk/subversion/libsvn_delta/compat.c Fri Nov 4 19:08:11 2011
@@ -27,6 +27,7 @@
#include "svn_sorts.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
+#include "svn_hash.h"
#include "svn_props.h"
#include "svn_pools.h"
@@ -619,8 +620,9 @@ struct operation {
const char *copyfrom_url; /* to copy, valid for add and replace */
const char *src_file; /* for put, the source file for contents */
apr_hash_t *children; /* const char *path -> struct operation * */
- apr_hash_t *props; /* const char *prop_name ->
+ apr_hash_t *prop_mods; /* const char *prop_name ->
const svn_string_t *prop_value */
+ apr_array_header_t *prop_dels; /* const char *prop_name deletions */
void *baton; /* as returned by the commit editor */
};
@@ -632,6 +634,9 @@ struct editor_baton
svn_delta_fetch_kind_func_t fetch_kind_func;
void *fetch_kind_baton;
+ svn_delta_fetch_props_func_t fetch_props_func;
+ void *fetch_props_baton;
+
struct operation root;
svn_boolean_t root_opened;
@@ -639,6 +644,18 @@ struct editor_baton
apr_pool_t *edit_pool;
};
+/* Calculate the diff between the old props and the new ones.
+ * This implements svn_hash_diff_func_t. */
+static svn_error_t *
+props_diff_func(const void *key,
+ apr_ssize_t klen,
+ enum svn_hash_diff_key_status status,
+ void *baton)
+{
+ return SVN_NO_ERROR;
+}
+
+
/* Find the operation associated with PATH, which is a single-path
component representing a child of the path represented by
OPERATION. If no such child operation exists, create a new one of
@@ -657,7 +674,8 @@ get_operation(const char *path,
child->operation = OP_OPEN;
child->copyfrom_revision = SVN_INVALID_REVNUM;
child->kind = svn_kind_dir;
- child->props = NULL;
+ child->prop_mods = apr_hash_make(result_pool);
+ child->prop_dels = apr_array_make(result_pool, 1, sizeof(const char *));
apr_hash_set(operation->children, apr_pstrdup(result_pool, path),
APR_HASH_KEY_STRING, child);
}
@@ -715,8 +733,15 @@ build(struct editor_baton *eb,
/* Handle property changes. */
if (props)
{
+ apr_hash_t *current_props;
+
SVN_ERR(eb->fetch_kind_func(&operation->kind, eb->fetch_kind_baton,
relpath, scratch_pool));
+ SVN_ERR(eb->fetch_props_func(¤t_props, eb->fetch_props_baton,
+ relpath, eb->edit_pool, scratch_pool));
+
+ SVN_ERR(svn_hash_diff(props, current_props, props_diff_func, operation,
+ scratch_pool));
/* If we're not adding this thing ourselves, check for existence. */
if (! ((operation->operation == OP_ADD) ||
@@ -726,7 +751,6 @@ build(struct editor_baton *eb,
&& (operation->operation == OP_OPEN))
operation->operation = OP_PROPSET;
}
- operation->props = svn_prop_hash_dup(props, eb->edit_pool);
if (!operation->copyfrom_revision)
operation->copyfrom_revision = rev;
return SVN_NO_ERROR;
@@ -994,6 +1018,54 @@ move_cb(void *baton,
}
static svn_error_t *
+change_props(const svn_delta_editor_t *editor,
+ void *baton,
+ struct operation *child,
+ apr_pool_t *scratch_pool)
+{
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+ if (child->prop_dels)
+ {
+ int i;
+ for (i = 0; i < child->prop_dels->nelts; i++)
+ {
+ const char *prop_name;
+
+ svn_pool_clear(iterpool);
+ prop_name = APR_ARRAY_IDX(child->prop_dels, i, const char *);
+ if (child->kind == svn_node_dir)
+ SVN_ERR(editor->change_dir_prop(baton, prop_name,
+ NULL, iterpool));
+ else
+ SVN_ERR(editor->change_file_prop(baton, prop_name,
+ NULL, iterpool));
+ }
+ }
+
+ if (apr_hash_count(child->prop_mods))
+ {
+ apr_hash_index_t *hi;
+ for (hi = apr_hash_first(scratch_pool, child->prop_mods);
+ hi; hi = apr_hash_next(hi))
+ {
+ const void *key;
+ void *val;
+
+ svn_pool_clear(iterpool);
+ apr_hash_this(hi, &key, NULL, &val);
+ if (child->kind == svn_node_dir)
+ SVN_ERR(editor->change_dir_prop(baton, key, val, iterpool));
+ else
+ SVN_ERR(editor->change_file_prop(baton, key, val, iterpool));
+ }
+ }
+
+ svn_pool_destroy(iterpool);
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
drive(const struct operation *operation,
const svn_delta_editor_t *editor,
apr_pool_t *scratch_pool)
@@ -1054,14 +1126,23 @@ drive(const struct operation *operation,
SVN_ERR(svn_stream_close(contents));
}
+ /* Only worry about properties and closing the file baton if we've
+ previously opened it. */
if (file_baton)
{
+ if (child->kind == svn_kind_file)
+ SVN_ERR(change_props(editor, file_baton, child, iterpool));
SVN_ERR(editor->close_file(file_baton, NULL, iterpool));
}
- /*SVN_DBG(("child: '%s'; operation: %d\n", path, child->operation));*/
+ /* We *always* open the child directory, so drive the child, change any
+ props, and then close the directory. */
if (child->kind == svn_kind_dir)
- SVN_ERR(drive(child, editor, iterpool));
+ {
+ SVN_ERR(drive(child, editor, iterpool));
+ SVN_ERR(change_props(editor, child->baton, child, iterpool));
+ SVN_ERR(editor->close_directory(child->baton, iterpool));
+ }
}
return SVN_NO_ERROR;
@@ -1121,6 +1202,8 @@ editor_from_delta(svn_editor_t **editor_
void *cancel_baton,
svn_delta_fetch_kind_func_t fetch_kind_func,
void *fetch_kind_baton,
+ svn_delta_fetch_props_func_t fetch_props_func,
+ void *fetch_props_baton,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -1148,11 +1231,14 @@ editor_from_delta(svn_editor_t **editor_
eb->fetch_kind_func = fetch_kind_func;
eb->fetch_kind_baton = fetch_kind_baton;
+ eb->fetch_props_func = fetch_props_func;
+ eb->fetch_props_baton = fetch_props_baton;
eb->root.children = apr_hash_make(result_pool);
eb->root.kind = svn_kind_dir;
eb->root.operation = OP_OPEN;
- eb->root.props = NULL;
+ eb->root.prop_mods = apr_hash_make(result_pool);
+ eb->root.prop_dels = apr_array_make(result_pool, 1, sizeof(const char *));
eb->root.copyfrom_revision = SVN_INVALID_REVNUM;
eb->root_opened = FALSE;
@@ -1204,6 +1290,8 @@ svn_editor__insert_shims(const svn_delta
SVN_ERR(editor_from_delta(&editor, deditor_in, dedit_baton_in,
NULL, NULL, shim_callbacks->fetch_kind_func,
shim_callbacks->fetch_kind_baton,
+ shim_callbacks->fetch_props_func,
+ shim_callbacks->fetch_props_baton,
result_pool, scratch_pool));
SVN_ERR(delta_from_editor(deditor_out, dedit_baton_out, editor,
shim_callbacks->fetch_props_func,