You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2012/02/02 14:37:32 UTC
svn commit: r1239613 [2/3] - in /subversion/branches/moves-scan-log: ./
notes/ subversion/bindings/javahl/ subversion/bindings/javahl/native/
subversion/bindings/swig/python/libsvn_swig_py/
subversion/bindings/swig/python/tests/ subversion/include/ sub...
Modified: subversion/branches/moves-scan-log/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_client/merge.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_client/merge.c Thu Feb 2 13:37:30 2012
@@ -9842,6 +9842,85 @@ find_unsynced_ranges(const char *source_
}
+/* Find the youngest revision that has been merged from target to source.
+ *
+ * If any location in TARGET_HISTORY_AS_MERGEINFO is mentioned in
+ * SOURCE_MERGEINFO, then we know that at least one merge was done from the
+ * target to the source. In that case, set *YOUNGEST_MERGED_REV to the
+ * youngest revision of that intersection (unless *YOUNGEST_MERGED_REV is
+ * already younger than that). Otherwise, leave *YOUNGEST_MERGED_REV alone.
+ */
+static svn_error_t *
+find_youngest_merged_rev(svn_revnum_t *youngest_merged_rev,
+ svn_mergeinfo_t target_history_as_mergeinfo,
+ svn_mergeinfo_t source_mergeinfo,
+ apr_pool_t *scratch_pool)
+{
+ svn_mergeinfo_t explicit_source_target_history_intersection;
+
+ SVN_ERR(svn_mergeinfo_intersect2(
+ &explicit_source_target_history_intersection,
+ source_mergeinfo, target_history_as_mergeinfo, TRUE,
+ scratch_pool, scratch_pool));
+ if (apr_hash_count(explicit_source_target_history_intersection))
+ {
+ svn_revnum_t old_rev, young_rev;
+
+ /* Keep track of the youngest revision merged from target to source. */
+ SVN_ERR(svn_mergeinfo__get_range_endpoints(
+ &young_rev, &old_rev,
+ explicit_source_target_history_intersection, scratch_pool));
+ if (!SVN_IS_VALID_REVNUM(*youngest_merged_rev)
+ || (young_rev > *youngest_merged_rev))
+ *youngest_merged_rev = young_rev;
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* Set *FILTERED_MERGEINFO_P to the parts of TARGET_HISTORY_AS_MERGEINFO
+ * that are not present in the source branch.
+ *
+ * SOURCE_MERGEINFO is the explicit or inherited mergeinfo of the source
+ * branch SOURCE_URL@SOURCE_REV. Extend SOURCE_MERGEINFO, modifying it in
+ * place, to include the natural history (implicit mergeinfo) of
+ * SOURCE_URL@SOURCE_REV. ### But make these additions in SCRATCH_POOL.
+ */
+static svn_error_t *
+find_unmerged_mergeinfo_subroutine(svn_mergeinfo_t *filtered_mergeinfo_p,
+ svn_mergeinfo_t target_history_as_mergeinfo,
+ svn_mergeinfo_t source_mergeinfo,
+ const char *source_url,
+ svn_revnum_t source_rev,
+ svn_ra_session_t *source_ra_session,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_mergeinfo_t source_history_as_mergeinfo;
+
+ /* Get the source path's natural history and merge it into source
+ path's explicit or inherited mergeinfo. */
+ SVN_ERR(svn_client__get_history_as_mergeinfo(
+ &source_history_as_mergeinfo, NULL /* has_rev_zero_history */,
+ source_url, source_rev, source_rev, SVN_INVALID_REVNUM,
+ source_ra_session, ctx, scratch_pool));
+ SVN_ERR(svn_mergeinfo_merge2(source_mergeinfo,
+ source_history_as_mergeinfo,
+ scratch_pool, scratch_pool));
+
+ /* Now source_mergeinfo represents everything we know about
+ source_path's history. Now we need to know what part, if any, of the
+ corresponding target's history is *not* part of source_path's total
+ history; because it is neither shared history nor was it ever merged
+ from the target to the source. */
+ SVN_ERR(svn_mergeinfo_remove2(filtered_mergeinfo_p,
+ source_mergeinfo,
+ target_history_as_mergeinfo, TRUE,
+ result_pool, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
/* Helper for calculate_left_hand_side() which produces a mergeinfo catalog
describing what parts of of the reintegrate target have not previously been
merged to the reintegrate source.
@@ -9884,8 +9963,7 @@ find_unsynced_ranges(const char *source_
TARGET_HISTORY_HASH.
If no part of TARGET_HISTORY_HASH is found in SOURCE_CATALOG set
- *NEVER_SYNCHED to TRUE and set *YOUNGEST_MERGED_REV to SVN_INVALID_REVNUM.
- Otherwise set *NEVER_SYNCHED to FALSE, *YOUNGEST_MERGED_REV to the youngest
+ *YOUNGEST_MERGED_REV to SVN_INVALID_REVNUM; otherwise set it to the youngest
revision previously merged from the target to the source, and filter
*UNMERGED_TO_SOURCE_CATALOG so that it contains no ranges greater than
*YOUNGEST_MERGED_REV.
@@ -9894,7 +9972,6 @@ find_unsynced_ranges(const char *source_
SCRATCH_POOL is used for all temporary allocations. */
static svn_error_t *
find_unmerged_mergeinfo(svn_mergeinfo_catalog_t *unmerged_to_source_catalog,
- svn_boolean_t *never_synched,
svn_revnum_t *youngest_merged_rev,
svn_revnum_t yc_ancestor_rev,
svn_mergeinfo_catalog_t source_catalog,
@@ -9914,9 +9991,7 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
apr_hash_index_t *hi;
svn_mergeinfo_catalog_t new_catalog = apr_hash_make(result_pool);
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
- svn_revnum_t old_rev, young_rev;
- *never_synched = TRUE;
*youngest_merged_rev = SVN_INVALID_REVNUM;
SVN_ERR(svn_ra_get_session_url(target_ra_session, &target_session_url,
@@ -9932,12 +10007,11 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
{
const char *target_path = svn__apr_hash_index_key(hi);
svn_mergeinfo_t target_history_as_mergeinfo = svn__apr_hash_index_val(hi);
- svn_mergeinfo_t source_history_as_mergeinfo;
const char *path_rel_to_session
= svn_relpath_skip_ancestor(target_repos_rel_path, target_path);
const char *source_path;
const char *source_url;
- svn_mergeinfo_t source_mergeinfo, filtered_mergeinfo, common_mergeinfo;
+ svn_mergeinfo_t source_mergeinfo, filtered_mergeinfo;
svn_pool_clear(iterpool);
@@ -9966,31 +10040,13 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
APR_HASH_KEY_STRING);
if (source_mergeinfo)
{
- svn_mergeinfo_t explicit_source_target_history_intersection;
-
apr_hash_set(source_catalog, source_path, APR_HASH_KEY_STRING,
NULL);
- /* If there is an intersection between the *explicit* mergeinfo on
- this source path and the corresponding target's history then we
- know that at least one merge was done from the target to the
- source. */
- SVN_ERR(svn_mergeinfo_intersect2(
- &explicit_source_target_history_intersection,
- source_mergeinfo, target_history_as_mergeinfo, TRUE,
- iterpool, iterpool));
- if (apr_hash_count(explicit_source_target_history_intersection))
- {
- *never_synched = FALSE;
- /* Keep track of the youngest revision merged from the
- target to the source. */
- SVN_ERR(svn_mergeinfo__get_range_endpoints(
- &young_rev, &old_rev,
- explicit_source_target_history_intersection,
- iterpool));
- if (!SVN_IS_VALID_REVNUM(*youngest_merged_rev)
- || (young_rev > *youngest_merged_rev))
- *youngest_merged_rev = young_rev;
- }
+
+ SVN_ERR(find_youngest_merged_rev(youngest_merged_rev,
+ target_history_as_mergeinfo,
+ source_mergeinfo,
+ iterpool));
}
else
{
@@ -10027,40 +10083,13 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
source_mergeinfo = apr_hash_make(iterpool);
}
- /* Get the source path's natural history and convert it to mergeinfo.
- Then merge that natural history into source path's explicit
- or inherited mergeinfo. */
- SVN_ERR(svn_client__get_history_as_mergeinfo(&source_history_as_mergeinfo,
- NULL /* has_rev_zero_history */,
- source_url,
- source_rev, source_rev,
- SVN_INVALID_REVNUM,
- source_ra_session,
- ctx, iterpool));
- SVN_ERR(svn_mergeinfo_merge2(source_mergeinfo,
- source_history_as_mergeinfo, iterpool,
- iterpool));
-
- /* Now source_mergeinfo represents everything we know about
- source_path's history. Now we need to know what part, if any, of the
- corresponding target's history is *not* part of source_path's total
- history; because it is neither shared history nor was it ever merged
- from the target to the source. */
- SVN_ERR(svn_mergeinfo_intersect2(&common_mergeinfo,
- source_mergeinfo,
- target_history_as_mergeinfo, TRUE,
- iterpool, iterpool));
-
- /* Use scratch_pool rather than iterpool because filtered_mergeinfo is
- going into new_catalog below and needs to last to the end of
+ /* Use scratch_pool rather than iterpool because filtered_mergeinfo
+ is going into new_catalog below and needs to last to the end of
this function. */
- SVN_ERR(svn_mergeinfo_remove2(&filtered_mergeinfo,
- common_mergeinfo,
- target_history_as_mergeinfo, TRUE,
- scratch_pool, iterpool));
-
- /* As with svn_mergeinfo_intersect above, we need to use scratch_pool
- rather than iterpool. */
+ SVN_ERR(find_unmerged_mergeinfo_subroutine(
+ &filtered_mergeinfo, target_history_as_mergeinfo,
+ source_mergeinfo, source_url, source_rev,
+ source_ra_session, ctx, scratch_pool, iterpool));
apr_hash_set(new_catalog,
apr_pstrdup(scratch_pool, source_path),
APR_HASH_KEY_STRING,
@@ -10081,9 +10110,9 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
svn_relpath_skip_ancestor(source_repos_rel_path, source_path);
const char *source_url;
svn_mergeinfo_t source_mergeinfo = svn__apr_hash_index_val(hi);
- svn_mergeinfo_t filtered_mergeinfo, common_mergeinfo;
+ svn_mergeinfo_t filtered_mergeinfo;
const char *target_url;
- svn_mergeinfo_t target_history_as_mergeinfo, source_history_as_mergeinfo;
+ svn_mergeinfo_t target_history_as_mergeinfo;
svn_error_t *err;
svn_pool_clear(iterpool);
@@ -10116,56 +10145,19 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
}
else
{
- svn_mergeinfo_t explicit_source_target_history_intersection;
-
- /* If there is an intersection between the *explicit* mergeinfo
- on this source path and the corresponding target's history
- then we know that at least one merge was done from the target
- to the source. */
- SVN_ERR(svn_mergeinfo_intersect2(
- &explicit_source_target_history_intersection,
- source_mergeinfo, target_history_as_mergeinfo, TRUE,
- iterpool, iterpool));
-
- if (apr_hash_count(explicit_source_target_history_intersection))
- {
- *never_synched = FALSE;
- /* Keep track of the youngest revision merged from the
- target to the source. */
- SVN_ERR(svn_mergeinfo__get_range_endpoints(
- &young_rev, &old_rev,
- explicit_source_target_history_intersection, iterpool));
- if (!SVN_IS_VALID_REVNUM(*youngest_merged_rev)
- || (young_rev > *youngest_merged_rev))
- *youngest_merged_rev = young_rev;
- }
-
- /* Get the source path's natural history and convert it to
- mergeinfo. Then merge that natural history into source
- path's explicit or inherited mergeinfo. */
- SVN_ERR(svn_client__get_history_as_mergeinfo(
- &source_history_as_mergeinfo,
- NULL /* has_rev_zero_history */,
- source_url,
- target_rev,
- target_rev,
- SVN_INVALID_REVNUM,
- source_ra_session,
- ctx, iterpool));
- SVN_ERR(svn_mergeinfo_merge2(source_mergeinfo,
- source_history_as_mergeinfo,
- iterpool, iterpool));
- SVN_ERR(svn_mergeinfo_intersect2(&common_mergeinfo,
- source_mergeinfo,
+ SVN_ERR(find_youngest_merged_rev(youngest_merged_rev,
target_history_as_mergeinfo,
- TRUE, iterpool, iterpool));
- /* Use subpool rather than iterpool because filtered_mergeinfo
- is going into new_catalog below and needs to last to the
- end of this function. */
- SVN_ERR(svn_mergeinfo_remove2(&filtered_mergeinfo,
- common_mergeinfo,
- target_history_as_mergeinfo,
- TRUE, scratch_pool, iterpool));
+ source_mergeinfo,
+ iterpool));
+
+ /* Use scratch_pool rather than iterpool because filtered_mergeinfo
+ is going into new_catalog below and needs to last to the end of
+ this function. */
+ /* ### Why looking at SOURCE_url at TARGET_rev? */
+ SVN_ERR(find_unmerged_mergeinfo_subroutine(
+ &filtered_mergeinfo, target_history_as_mergeinfo,
+ source_mergeinfo, source_url, target_rev,
+ source_ra_session, ctx, scratch_pool, iterpool));
if (apr_hash_count(filtered_mergeinfo))
apr_hash_set(new_catalog,
apr_pstrdup(scratch_pool, source_path),
@@ -10251,7 +10243,6 @@ calculate_left_hand_side(const char **ur
apr_hash_index_t *hi;
/* hash of paths mapped to arrays of svn_mergeinfo_t. */
apr_hash_t *target_history_hash = apr_hash_make(scratch_pool);
- svn_boolean_t never_synced;
svn_revnum_t youngest_merged_rev;
const char *yc_ancestor_url;
svn_revnum_t yc_ancestor_rev;
@@ -10359,7 +10350,6 @@ calculate_left_hand_side(const char **ur
mergeinfo that describes what has *not* previously been merged from
TARGET_REPOS_REL_PATH@TARGET_REV to SOURCE_REPOS_REL_PATH@SOURCE_REV. */
SVN_ERR(find_unmerged_mergeinfo(&unmerged_catalog,
- &never_synced,
&youngest_merged_rev,
yc_ancestor_rev,
mergeinfo_catalog,
@@ -10379,7 +10369,7 @@ calculate_left_hand_side(const char **ur
*unmerged_to_source_catalog = svn_mergeinfo_catalog_dup(unmerged_catalog,
result_pool);
- if (never_synced)
+ if (youngest_merged_rev == SVN_INVALID_REVNUM)
{
/* We never merged to the source. Just return the branch point. */
*url_left = apr_pstrdup(result_pool, yc_ancestor_url);
Modified: subversion/branches/moves-scan-log/subversion/libsvn_delta/compat.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_delta/compat.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_delta/compat.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_delta/compat.c Thu Feb 2 13:37:30 2012
@@ -91,7 +91,18 @@ svn_compat_wrap_file_rev_handler(svn_fil
* The general idea here is that we have to see *all* the actions on a node's
* parent before we can process that node, which means we need to buffer a
* large amount of information in the dir batons, and then process it in the
- * close_directory() handler. */
+ * close_directory() handler.
+ *
+ * There are a few ways we alter the callback stream. One is when unlocking
+ * paths. To tell a client a path should be unlocked, the server sends a
+ * prop-del for the SVN_PROP_ENTRY_LOCK_TOKEN property. This causes problems,
+ * since the client doesn't have this property in the first place, but the
+ * deletion has side effects (unlike deleting a non-existent regular property
+ * would). To solve this, we introduce *another* function into the API, not
+ * a part of the Ev2 callbacks, but a companion which is used to register
+ * the unlock of a path. See ev2_change_file_prop() for implemenation
+ * details.
+ */
typedef svn_error_t *(*start_edit_func_t)(
void *baton,
@@ -102,6 +113,11 @@ typedef svn_error_t *(*target_revision_f
svn_revnum_t target_revision,
apr_pool_t *scratch_pool);
+typedef svn_error_t *(*unlock_func_t)(
+ void *baton,
+ const char *path,
+ apr_pool_t *scratch_pool);
+
/* svn_editor__See insert_shims() for more information. */
struct extra_baton
{
@@ -125,6 +141,9 @@ struct ev2_edit_baton
svn_delta_fetch_base_func_t fetch_base_func;
void *fetch_base_baton;
+
+ unlock_func_t do_unlock;
+ void *unlock_baton;
};
struct ev2_dir_baton
@@ -155,7 +174,8 @@ enum action_code_t
ACTION_ADD,
ACTION_DELETE,
ACTION_ADD_ABSENT,
- ACTION_SET_TEXT
+ ACTION_SET_TEXT,
+ ACTION_UNLOCK
};
struct path_action
@@ -261,10 +281,13 @@ process_actions(void *edit_baton,
{
/* Fetch the original props. We can then apply each of
the modifications to it. */
- SVN_ERR(eb->fetch_props_func(&props,
- eb->fetch_props_baton,
- path, props_base_revision,
- scratch_pool, scratch_pool));
+ if (need_delete && need_add)
+ props = apr_hash_make(scratch_pool);
+ else
+ SVN_ERR(eb->fetch_props_func(&props,
+ eb->fetch_props_baton,
+ path, props_base_revision,
+ scratch_pool, scratch_pool));
}
/* Note that p_args->value may be NULL. */
@@ -334,6 +357,12 @@ process_actions(void *edit_baton,
break;
}
+ case ACTION_UNLOCK:
+ {
+ SVN_ERR(eb->do_unlock(eb->unlock_baton, path, scratch_pool));
+ break;
+ }
+
default:
SVN_ERR_MALFUNCTION();
}
@@ -751,6 +780,15 @@ ev2_change_file_prop(void *file_baton,
struct ev2_file_baton *fb = file_baton;
struct prop_args *p_args = apr_palloc(fb->eb->edit_pool, sizeof(*p_args));
+ if (!strcmp(name, SVN_PROP_ENTRY_LOCK_TOKEN) && value == NULL)
+ {
+ /* We special case the lock token propery deletion, which is the
+ server's way of telling the client to unlock the path. */
+ SVN_ERR(add_action(fb->eb, fb->path, ACTION_UNLOCK, NULL));
+ }
+
+ /* We also pass through the deletion, since there may actually exist such
+ a property we want to get rid of. In the worse case, this is a no-op. */
p_args->name = apr_pstrdup(fb->eb->edit_pool, name);
p_args->value = value ? svn_string_dup(value, fb->eb->edit_pool) : NULL;
p_args->base_revision = fb->base_revision;
@@ -802,10 +840,32 @@ ev2_abort_edit(void *edit_baton,
return svn_error_trace(svn_editor_abort(eb->editor));
}
+/* Return a svn_delta_editor_t * in DEDITOR, with an accompanying baton in
+ * DEDITOR_BATON, which will be driven by EDITOR. These will both be
+ * allocated in RESULT_POOL, which may become large and long-lived;
+ * SCRATCH_POOL is used for temporary allocations.
+ *
+ * The other parameters are as follows:
+ * - UNLOCK_FUNC / UNLOCK_BATON: A callback / baton which will be called
+ * when an unlocking action is received.
+ * - FOUND_ABS_PATHS: A pointer to a boolean flag which will be set if
+ * this shim determines that it is receiving absolute paths.
+ * - FETCH_PROPS_FUNC / FETCH_PROPS_BATON: A callback / baton pair which
+ * will be used by the shim handlers if they need to determine the
+ * existing properties on a path.
+ * - FETCH_BASE_FUNC / FETCH_BASE_BATON: A callback / baton pair which will
+ * be used by the shims handlers if they need to determine the base
+ * text of a path. It should only be invoked for files.
+ * - EXB: An 'extra baton' which is used to communicate between the shims.
+ * Its callbacks should be invoked at the appropriate time by this
+ * shim.
+ */
static svn_error_t *
delta_from_editor(const svn_delta_editor_t **deditor,
void **dedit_baton,
svn_editor_t *editor,
+ unlock_func_t unlock_func,
+ void *unlock_baton,
svn_boolean_t *found_abs_paths,
svn_delta_fetch_props_func_t fetch_props_func,
void *fetch_props_baton,
@@ -848,6 +908,9 @@ delta_from_editor(const svn_delta_editor
eb->fetch_base_func = fetch_base_func;
eb->fetch_base_baton = fetch_base_baton;
+ eb->do_unlock = unlock_func;
+ eb->unlock_baton = unlock_baton;
+
*dedit_baton = eb;
*deditor = &delta_editor;
@@ -874,6 +937,7 @@ struct operation {
svn_kind_t kind; /* to copy, mkdir, put or set revprops */
svn_revnum_t base_revision; /* When committing, the base revision */
svn_revnum_t copyfrom_revision; /* to copy, valid for add and replace */
+ svn_checksum_t *new_checksum; /* An MD5 hash of the new contents, if any */
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 * */
@@ -895,7 +959,6 @@ struct editor_baton
void *fetch_props_baton;
struct operation root;
- svn_boolean_t root_opened;
svn_boolean_t *make_abs_paths;
apr_hash_t *paths;
@@ -929,6 +992,11 @@ get_operation(const char *path,
apr_hash_set(operation->children, apr_pstrdup(result_pool, path),
APR_HASH_KEY_STRING, child);
}
+
+ /* If an operation has a child, it must of necessity be a directory,
+ so ensure this fact. */
+ operation->kind = svn_kind_dir;
+
return child;
}
@@ -957,6 +1025,7 @@ build(struct editor_baton *eb,
svn_revnum_t rev,
apr_hash_t *props,
const char *src_file,
+ svn_checksum_t *checksum,
svn_revnum_t head,
apr_pool_t *scratch_pool)
{
@@ -986,14 +1055,23 @@ build(struct editor_baton *eb,
apr_hash_t *current_props;
apr_array_header_t *propdiffs;
- if (kind == svn_kind_unknown)
- SVN_ERR(eb->fetch_kind_func(&operation->kind, eb->fetch_kind_baton,
- relpath, rev, scratch_pool));
- else
- operation->kind = kind;
+ /* Only fetch the kind if operating on something other than the root,
+ as we already know the kind on the root. */
+ if (operation->path)
+ {
+ if (kind == svn_kind_unknown)
+ SVN_ERR(eb->fetch_kind_func(&operation->kind, eb->fetch_kind_baton,
+ relpath, rev, scratch_pool));
+ else
+ operation->kind = kind;
+ }
- SVN_ERR(eb->fetch_props_func(¤t_props, eb->fetch_props_baton,
- relpath, rev, scratch_pool, scratch_pool));
+ if (operation->operation == OP_REPLACE)
+ current_props = apr_hash_make(scratch_pool);
+ else
+ SVN_ERR(eb->fetch_props_func(¤t_props, eb->fetch_props_baton,
+ relpath, rev, scratch_pool,
+ scratch_pool));
SVN_ERR(svn_prop_diffs(&propdiffs, props, current_props, scratch_pool));
@@ -1006,7 +1084,9 @@ build(struct editor_baton *eb,
APR_ARRAY_PUSH(operation->prop_dels, const char *) =
apr_pstrdup(eb->edit_pool, prop->name);
else
- apr_hash_set(operation->prop_mods, prop->name, APR_HASH_KEY_STRING,
+ apr_hash_set(operation->prop_mods,
+ apr_pstrdup(eb->edit_pool, prop->name),
+ APR_HASH_KEY_STRING,
svn_string_dup(prop->value, eb->edit_pool));
}
@@ -1024,7 +1104,10 @@ build(struct editor_baton *eb,
}
if (action == ACTION_DELETE)
- operation->operation = OP_DELETE;
+ {
+ operation->operation = OP_DELETE;
+ operation->base_revision = rev;
+ }
else if (action == ACTION_ADD_ABSENT)
operation->operation = OP_ADD_ABSENT;
@@ -1068,7 +1151,8 @@ build(struct editor_baton *eb,
"'%s' is not a file", relpath);
}
operation->kind = svn_kind_file;
- operation->src_file = src_file;
+ operation->src_file = apr_pstrdup(eb->edit_pool, src_file);
+ operation->new_checksum = svn_checksum_dup(checksum, eb->edit_pool);
}
else
{
@@ -1079,19 +1163,6 @@ build(struct editor_baton *eb,
return SVN_NO_ERROR;
}
-static svn_error_t *
-ensure_root_opened(struct editor_baton *eb)
-{
- if (!eb->root_opened)
- {
- SVN_ERR(eb->deditor->open_root(eb->dedit_baton, eb->root.base_revision,
- eb->edit_pool, &eb->root.baton));
- eb->root_opened = TRUE;
- }
-
- return SVN_NO_ERROR;
-}
-
/* This implements svn_editor_cb_add_directory_t */
static svn_error_t *
add_directory_cb(void *baton,
@@ -1103,25 +1174,23 @@ add_directory_cb(void *baton,
{
struct editor_baton *eb = baton;
- SVN_ERR(ensure_root_opened(eb));
-
if (SVN_IS_VALID_REVNUM(replaces_rev))
{
/* We need to add the delete action. */
SVN_ERR(build(eb, ACTION_DELETE, relpath, svn_kind_unknown,
NULL, SVN_INVALID_REVNUM,
- NULL, NULL, SVN_INVALID_REVNUM, scratch_pool));
+ NULL, NULL, NULL, SVN_INVALID_REVNUM, scratch_pool));
}
SVN_ERR(build(eb, ACTION_MKDIR, relpath, svn_kind_dir,
NULL, SVN_INVALID_REVNUM,
- NULL, NULL, SVN_INVALID_REVNUM, scratch_pool));
+ NULL, NULL, NULL, SVN_INVALID_REVNUM, scratch_pool));
if (props && apr_hash_count(props) > 0)
SVN_ERR(build(eb, ACTION_PROPSET, relpath, svn_kind_dir,
NULL, SVN_INVALID_REVNUM, props,
- NULL, SVN_INVALID_REVNUM, scratch_pool));
+ NULL, NULL, SVN_INVALID_REVNUM, scratch_pool));
return SVN_NO_ERROR;
}
@@ -1139,8 +1208,14 @@ add_file_cb(void *baton,
struct editor_baton *eb = baton;
const char *tmp_filename;
svn_stream_t *tmp_stream;
+ svn_checksum_t *md5_checksum;
- SVN_ERR(ensure_root_opened(eb));
+ /* We may need to re-checksum these contents */
+ if (!(checksum && checksum->kind == svn_checksum_md5))
+ contents = svn_stream_checksummed2(contents, &md5_checksum, NULL,
+ svn_checksum_md5, TRUE, scratch_pool);
+ else
+ md5_checksum = (svn_checksum_t *)checksum;
if (SVN_IS_VALID_REVNUM(replaces_rev))
{
@@ -1148,24 +1223,24 @@ add_file_cb(void *baton,
SVN_ERR(build(eb, ACTION_DELETE, relpath, svn_kind_unknown,
NULL, SVN_INVALID_REVNUM,
- NULL, NULL, SVN_INVALID_REVNUM, scratch_pool));
+ NULL, NULL, NULL, SVN_INVALID_REVNUM, scratch_pool));
}
/* Spool the contents to a tempfile, and provide that to the driver. */
SVN_ERR(svn_stream_open_unique(&tmp_stream, &tmp_filename, NULL,
svn_io_file_del_on_pool_cleanup,
eb->edit_pool, scratch_pool));
- SVN_ERR(svn_stream_copy3(svn_stream_disown(contents, scratch_pool),
- tmp_stream, NULL, NULL, scratch_pool));
+ SVN_ERR(svn_stream_copy3(contents, tmp_stream, NULL, NULL, scratch_pool));
SVN_ERR(build(eb, ACTION_PUT, relpath, svn_kind_none,
NULL, SVN_INVALID_REVNUM,
- NULL, tmp_filename, SVN_INVALID_REVNUM, scratch_pool));
+ NULL, tmp_filename, md5_checksum, SVN_INVALID_REVNUM,
+ scratch_pool));
if (props && apr_hash_count(props) > 0)
SVN_ERR(build(eb, ACTION_PROPSET, relpath, svn_kind_file,
NULL, SVN_INVALID_REVNUM, props,
- NULL, SVN_INVALID_REVNUM, scratch_pool));
+ NULL, NULL, SVN_INVALID_REVNUM, scratch_pool));
return SVN_NO_ERROR;
}
@@ -1181,15 +1256,13 @@ add_symlink_cb(void *baton,
{
struct editor_baton *eb = baton;
- SVN_ERR(ensure_root_opened(eb));
-
if (SVN_IS_VALID_REVNUM(replaces_rev))
{
/* We need to add the delete action. */
SVN_ERR(build(eb, ACTION_DELETE, relpath, svn_kind_unknown,
NULL, SVN_INVALID_REVNUM,
- NULL, NULL, SVN_INVALID_REVNUM, scratch_pool));
+ NULL, NULL, NULL, SVN_INVALID_REVNUM, scratch_pool));
}
return SVN_NO_ERROR;
@@ -1205,11 +1278,9 @@ add_absent_cb(void *baton,
{
struct editor_baton *eb = baton;
- SVN_ERR(ensure_root_opened(eb));
-
SVN_ERR(build(eb, ACTION_ADD_ABSENT, relpath, kind,
NULL, SVN_INVALID_REVNUM,
- NULL, NULL, SVN_INVALID_REVNUM, scratch_pool));
+ NULL, NULL, NULL, SVN_INVALID_REVNUM, scratch_pool));
return SVN_NO_ERROR;
}
@@ -1225,11 +1296,9 @@ set_props_cb(void *baton,
{
struct editor_baton *eb = baton;
- SVN_ERR(ensure_root_opened(eb));
-
SVN_ERR(build(eb, ACTION_PROPSET, relpath, svn_kind_unknown,
NULL, SVN_INVALID_REVNUM,
- props, NULL, revision, scratch_pool));
+ props, NULL, NULL, revision, scratch_pool));
return SVN_NO_ERROR;
}
@@ -1246,19 +1315,24 @@ set_text_cb(void *baton,
struct editor_baton *eb = baton;
const char *tmp_filename;
svn_stream_t *tmp_stream;
+ svn_checksum_t *md5_checksum;
- SVN_ERR(ensure_root_opened(eb));
+ /* We may need to re-checksum these contents */
+ if (!(checksum && checksum->kind == svn_checksum_md5))
+ contents = svn_stream_checksummed2(contents, &md5_checksum, NULL,
+ svn_checksum_md5, TRUE, scratch_pool);
+ else
+ md5_checksum = (svn_checksum_t *)checksum;
/* Spool the contents to a tempfile, and provide that to the driver. */
SVN_ERR(svn_stream_open_unique(&tmp_stream, &tmp_filename, NULL,
svn_io_file_del_on_pool_cleanup,
eb->edit_pool, scratch_pool));
- SVN_ERR(svn_stream_copy3(svn_stream_disown(contents, scratch_pool),
- tmp_stream, NULL, NULL, scratch_pool));
+ SVN_ERR(svn_stream_copy3(contents, tmp_stream, NULL, NULL, scratch_pool));
SVN_ERR(build(eb, ACTION_PUT, relpath, svn_kind_file,
NULL, SVN_INVALID_REVNUM,
- NULL, tmp_filename, revision, scratch_pool));
+ NULL, tmp_filename, md5_checksum, revision, scratch_pool));
return SVN_NO_ERROR;
}
@@ -1273,8 +1347,6 @@ set_target_cb(void *baton,
{
struct editor_baton *eb = baton;
- SVN_ERR(ensure_root_opened(eb));
-
return SVN_NO_ERROR;
}
@@ -1287,10 +1359,8 @@ delete_cb(void *baton,
{
struct editor_baton *eb = baton;
- SVN_ERR(ensure_root_opened(eb));
-
SVN_ERR(build(eb, ACTION_DELETE, relpath, svn_kind_unknown,
- NULL, SVN_INVALID_REVNUM, NULL, NULL, SVN_INVALID_REVNUM,
+ NULL, revision, NULL, NULL, NULL, SVN_INVALID_REVNUM,
scratch_pool));
return SVN_NO_ERROR;
@@ -1307,20 +1377,18 @@ copy_cb(void *baton,
{
struct editor_baton *eb = baton;
- SVN_ERR(ensure_root_opened(eb));
-
if (SVN_IS_VALID_REVNUM(replaces_rev))
{
/* We need to add the delete action. */
SVN_ERR(build(eb, ACTION_DELETE, dst_relpath, svn_kind_unknown,
NULL, SVN_INVALID_REVNUM,
- NULL, NULL, SVN_INVALID_REVNUM, scratch_pool));
+ NULL, NULL, NULL, SVN_INVALID_REVNUM, scratch_pool));
}
SVN_ERR(build(eb, ACTION_COPY, dst_relpath, svn_kind_unknown,
- src_relpath, src_revision, NULL, NULL, SVN_INVALID_REVNUM,
- scratch_pool));
+ src_relpath, src_revision, NULL, NULL, NULL,
+ SVN_INVALID_REVNUM, scratch_pool));
return SVN_NO_ERROR;
}
@@ -1336,7 +1404,17 @@ move_cb(void *baton,
{
struct editor_baton *eb = baton;
- SVN_ERR(ensure_root_opened(eb));
+ return SVN_NO_ERROR;
+}
+
+/* This implements svn_editor_cb_rotate_t */
+static svn_error_t *
+rotate_cb(void *baton,
+ const apr_array_header_t *relpaths,
+ const apr_array_header_t *revisions,
+ apr_pool_t *scratch_pool)
+{
+ struct editor_baton *eb = baton;
return SVN_NO_ERROR;
}
@@ -1403,7 +1481,7 @@ drive_tree(struct operation *op,
/* Deletes and replacements are simple -- just delete the thing. */
if (op->operation == OP_DELETE || op->operation == OP_REPLACE)
{
- SVN_ERR(editor->delete_entry(path, SVN_INVALID_REVNUM,
+ SVN_ERR(editor->delete_entry(path, op->base_revision,
parent_op->baton, scratch_pool));
}
@@ -1411,8 +1489,7 @@ drive_tree(struct operation *op,
{
/* Open or create our baton. */
if (op->operation == OP_OPEN || op->operation == OP_PROPSET)
- SVN_ERR(editor->open_directory(path, parent_op->baton,
- parent_op->base_revision,
+ SVN_ERR(editor->open_directory(path, parent_op->baton, op->base_revision,
scratch_pool, &op->baton));
else if (op->operation == OP_ADD || op->operation == OP_REPLACE)
@@ -1488,7 +1565,10 @@ drive_tree(struct operation *op,
SVN_ERR(change_props(editor, file_baton, op, scratch_pool));
/* Close the file. */
- SVN_ERR(editor->close_file(file_baton, NULL, scratch_pool));
+ SVN_ERR(editor->close_file(file_baton,
+ svn_checksum_to_cstring(op->new_checksum,
+ scratch_pool),
+ scratch_pool));
}
}
@@ -1540,8 +1620,6 @@ complete_cb(void *baton,
struct editor_baton *eb = baton;
svn_error_t *err;
- SVN_ERR(ensure_root_opened(eb));
-
/* Drive the tree we've created. */
err = drive_root(&eb->root, eb->deditor, *eb->make_abs_paths, scratch_pool);
if (!err)
@@ -1592,7 +1670,8 @@ start_edit_func(void *baton,
struct editor_baton *eb = baton;
eb->root.base_revision = base_revision;
- SVN_ERR(ensure_root_opened(eb));
+ SVN_ERR(eb->deditor->open_root(eb->dedit_baton, eb->root.base_revision,
+ eb->edit_pool, &eb->root.baton));
return SVN_NO_ERROR;
}
@@ -1611,8 +1690,65 @@ target_revision_func(void *baton,
}
static svn_error_t *
+do_unlock(void *baton,
+ const char *path,
+ apr_pool_t *scratch_pool)
+{
+ struct editor_baton *eb = baton;
+ apr_array_header_t *path_bits = svn_path_decompose(path, scratch_pool);
+ const char *path_so_far = "";
+ struct operation *operation = &eb->root;
+ int i;
+
+ /* Look for any previous operations we've recognized for PATH. If
+ any of PATH's ancestors have not yet been traversed, we'll be
+ creating OP_OPEN operations for them as we walk down PATH's path
+ components. */
+ for (i = 0; i < path_bits->nelts; ++i)
+ {
+ const char *path_bit = APR_ARRAY_IDX(path_bits, i, const char *);
+ path_so_far = svn_relpath_join(path_so_far, path_bit, scratch_pool);
+ operation = get_operation(path_so_far, operation, SVN_INVALID_REVNUM,
+ eb->edit_pool);
+ }
+
+ APR_ARRAY_PUSH(operation->prop_dels, const char *) =
+ SVN_PROP_ENTRY_LOCK_TOKEN;
+
+ return SVN_NO_ERROR;
+}
+
+/* Return an svn_editor_t * in EDITOR_P which will be driven by
+ * DEDITOR/DEDIT_BATON. EDITOR_P is allocated in RESULT_POOL, which may
+ * become large and long-lived; SCRATCH_POOL is used for temporary
+ * allocations.
+ *
+ * The other parameters are as follows:
+ * - EXB: An 'extra_baton' used for passing information between the coupled
+ * shims. This includes actions like 'start edit' and 'set target'.
+ * As this shim receives these actions, it provides the extra baton
+ * to its caller.
+ * - UNLOCK_FUNC / UNLOCK_BATON: A callback / baton pair which a caller
+ * can use to notify this shim that a path should be unlocked (in the
+ * 'svn lock' sense). As this shim receives this action, it provides
+ * this callback / baton to its caller.
+ * - SEND_ABS_PATHS: A pointer which will be set prior to this edit (but
+ * not necessarily at the invocation of editor_from_delta()),and
+ * which indicates whether incoming paths should be expected to
+ * be absolute or relative.
+ * - CANCEL_FUNC / CANCEL_BATON: The usual; folded into the produced editor.
+ * - FETCH_KIND_FUNC / FETCH_KIND_BATON: A callback / baton pair which will
+ * be used by the shim handlers if they need to determine the kind of
+ * a path.
+ * - FETCH_PROPS_FUNC / FETCH_PROPS_BATON: A callback / baton pair which
+ * will be used by the shim handlers if they need to determine the
+ * existing properties on a path.
+ */
+static svn_error_t *
editor_from_delta(svn_editor_t **editor_p,
struct extra_baton **exb,
+ unlock_func_t *unlock_func,
+ void **unlock_baton,
const svn_delta_editor_t *deditor,
void *dedit_baton,
svn_boolean_t *send_abs_paths,
@@ -1637,6 +1773,7 @@ editor_from_delta(svn_editor_t **editor_
delete_cb,
copy_cb,
move_cb,
+ rotate_cb,
complete_cb,
abort_cb
};
@@ -1662,7 +1799,6 @@ editor_from_delta(svn_editor_t **editor_
eb->root.prop_dels = apr_array_make(result_pool, 1, sizeof(const char *));
eb->root.copyfrom_revision = SVN_INVALID_REVNUM;
- eb->root_opened = FALSE;
eb->make_abs_paths = send_abs_paths;
SVN_ERR(svn_editor_create(&editor, eb, cancel_func, cancel_baton,
@@ -1671,6 +1807,9 @@ editor_from_delta(svn_editor_t **editor_
*editor_p = editor;
+ *unlock_func = do_unlock;
+ *unlock_baton = eb;
+
extra_baton->start_edit = start_edit_func;
extra_baton->target_revision = target_revision_func;
extra_baton->baton = eb;
@@ -1723,7 +1862,11 @@ svn_editor__insert_shims(const svn_delta
svn_boolean_t *found_abs_paths = apr_palloc(result_pool,
sizeof(*found_abs_paths));
- SVN_ERR(editor_from_delta(&editor, &exb, deditor_in, dedit_baton_in,
+ unlock_func_t unlock_func;
+ void *unlock_baton;
+
+ SVN_ERR(editor_from_delta(&editor, &exb, &unlock_func, &unlock_baton,
+ deditor_in, dedit_baton_in,
found_abs_paths, NULL, NULL,
shim_callbacks->fetch_kind_func,
shim_callbacks->fetch_baton,
@@ -1731,6 +1874,7 @@ svn_editor__insert_shims(const svn_delta
shim_callbacks->fetch_baton,
result_pool, scratch_pool));
SVN_ERR(delta_from_editor(deditor_out, dedit_baton_out, editor,
+ unlock_func, unlock_baton,
found_abs_paths,
shim_callbacks->fetch_props_func,
shim_callbacks->fetch_baton,
Modified: subversion/branches/moves-scan-log/subversion/libsvn_delta/editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_delta/editor.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_delta/editor.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_delta/editor.c Thu Feb 2 13:37:30 2012
@@ -192,6 +192,16 @@ svn_editor_setcb_move(svn_editor_t *edit
svn_error_t *
+svn_editor_setcb_rotate(svn_editor_t *editor,
+ svn_editor_cb_rotate_t callback,
+ apr_pool_t *scratch_pool)
+{
+ editor->funcs.cb_rotate = callback;
+ return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
svn_editor_setcb_complete(svn_editor_t *editor,
svn_editor_cb_complete_t callback,
apr_pool_t *scratch_pool)
@@ -228,6 +238,7 @@ svn_editor_setcb_many(svn_editor_t *edit
COPY_CALLBACK(cb_delete);
COPY_CALLBACK(cb_copy);
COPY_CALLBACK(cb_move);
+ COPY_CALLBACK(cb_rotate);
COPY_CALLBACK(cb_complete);
COPY_CALLBACK(cb_abort);
@@ -244,9 +255,8 @@ svn_editor_add_directory(svn_editor_t *e
apr_hash_t *props,
svn_revnum_t replaces_rev)
{
- svn_error_t *err;
+ svn_error_t *err = SVN_NO_ERROR;
- SVN_ERR_ASSERT(editor->funcs.cb_add_directory != NULL);
#ifdef ENABLE_ORDERING_CHECK
SVN_ERR_ASSERT(!editor->finished);
SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, relpath,
@@ -256,9 +266,10 @@ svn_editor_add_directory(svn_editor_t *e
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
- err = editor->funcs.cb_add_directory(editor->baton, relpath, children,
- props, replaces_rev,
- editor->scratch_pool);
+ if (editor->funcs.cb_add_directory)
+ err = editor->funcs.cb_add_directory(editor->baton, relpath, children,
+ props, replaces_rev,
+ editor->scratch_pool);
#ifdef ENABLE_ORDERING_CHECK
apr_hash_set(editor->completed_nodes,
apr_pstrdup(editor->result_pool, relpath),
@@ -291,9 +302,8 @@ svn_editor_add_file(svn_editor_t *editor
apr_hash_t *props,
svn_revnum_t replaces_rev)
{
- svn_error_t *err;
+ svn_error_t *err = SVN_NO_ERROR;
- SVN_ERR_ASSERT(editor->funcs.cb_add_file != NULL);
#ifdef ENABLE_ORDERING_CHECK
SVN_ERR_ASSERT(!editor->finished);
SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, relpath,
@@ -303,9 +313,10 @@ svn_editor_add_file(svn_editor_t *editor
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
- err = editor->funcs.cb_add_file(editor->baton, relpath,
- checksum, contents, props,
- replaces_rev, editor->scratch_pool);
+ if (editor->funcs.cb_add_file)
+ err = editor->funcs.cb_add_file(editor->baton, relpath,
+ checksum, contents, props,
+ replaces_rev, editor->scratch_pool);
#ifdef ENABLE_ORDERING_CHECK
apr_hash_set(editor->completed_nodes,
apr_pstrdup(editor->result_pool, relpath),
@@ -325,9 +336,8 @@ svn_editor_add_symlink(svn_editor_t *edi
apr_hash_t *props,
svn_revnum_t replaces_rev)
{
- svn_error_t *err;
+ svn_error_t *err = SVN_NO_ERROR;
- SVN_ERR_ASSERT(editor->funcs.cb_add_symlink != NULL);
#ifdef ENABLE_ORDERING_CHECK
SVN_ERR_ASSERT(!editor->finished);
SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, relpath,
@@ -337,8 +347,9 @@ svn_editor_add_symlink(svn_editor_t *edi
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
- err = editor->funcs.cb_add_symlink(editor->baton, relpath, target, props,
- replaces_rev, editor->scratch_pool);
+ if (editor->funcs.cb_add_symlink)
+ err = editor->funcs.cb_add_symlink(editor->baton, relpath, target, props,
+ replaces_rev, editor->scratch_pool);
#ifdef ENABLE_ORDERING_CHECK
apr_hash_set(editor->completed_nodes,
apr_pstrdup(editor->result_pool, relpath),
@@ -357,9 +368,8 @@ svn_editor_add_absent(svn_editor_t *edit
svn_kind_t kind,
svn_revnum_t replaces_rev)
{
- svn_error_t *err;
+ svn_error_t *err = SVN_NO_ERROR;
- SVN_ERR_ASSERT(editor->funcs.cb_add_absent != NULL);
#ifdef ENABLE_ORDERING_CHECK
SVN_ERR_ASSERT(!editor->finished);
SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, relpath,
@@ -369,8 +379,9 @@ svn_editor_add_absent(svn_editor_t *edit
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
- err = editor->funcs.cb_add_absent(editor->baton, relpath, kind,
- replaces_rev, editor->scratch_pool);
+ if (editor->funcs.cb_add_absent)
+ err = editor->funcs.cb_add_absent(editor->baton, relpath, kind,
+ replaces_rev, editor->scratch_pool);
#ifdef ENABLE_ORDERING_CHECK
apr_hash_set(editor->completed_nodes,
apr_pstrdup(editor->result_pool, relpath),
@@ -390,9 +401,8 @@ svn_editor_set_props(svn_editor_t *edito
apr_hash_t *props,
svn_boolean_t complete)
{
- svn_error_t *err;
+ svn_error_t *err = SVN_NO_ERROR;
- SVN_ERR_ASSERT(editor->funcs.cb_set_props != NULL);
#ifdef ENABLE_ORDERING_CHECK
SVN_ERR_ASSERT(!editor->finished);
SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, relpath,
@@ -402,8 +412,9 @@ svn_editor_set_props(svn_editor_t *edito
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
- err = editor->funcs.cb_set_props(editor->baton, relpath, revision, props,
- complete, editor->scratch_pool);
+ if (editor->funcs.cb_set_props)
+ err = editor->funcs.cb_set_props(editor->baton, relpath, revision, props,
+ complete, editor->scratch_pool);
#ifdef ENABLE_ORDERING_CHECK
/* ### Some of the ordering here depends upon the kind of RELPATH, but
* ### we have no way of determining what that is. */
@@ -432,9 +443,8 @@ svn_editor_set_text(svn_editor_t *editor
const svn_checksum_t *checksum,
svn_stream_t *contents)
{
- svn_error_t *err;
+ svn_error_t *err = SVN_NO_ERROR;
- SVN_ERR_ASSERT(editor->funcs.cb_set_text != NULL);
#ifdef ENABLE_ORDERING_CHECK
SVN_ERR_ASSERT(!editor->finished);
SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, relpath,
@@ -444,8 +454,9 @@ svn_editor_set_text(svn_editor_t *editor
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
- err = editor->funcs.cb_set_text(editor->baton, relpath, revision,
- checksum, contents, editor->scratch_pool);
+ if (editor->funcs.cb_set_text)
+ err = editor->funcs.cb_set_text(editor->baton, relpath, revision,
+ checksum, contents, editor->scratch_pool);
#ifdef ENABLE_ORDERING_CHECK
apr_hash_set(editor->needs_text_or_target, relpath, APR_HASH_KEY_STRING,
NULL);
@@ -464,9 +475,8 @@ svn_editor_set_target(svn_editor_t *edit
svn_revnum_t revision,
const char *target)
{
- svn_error_t *err;
+ svn_error_t *err = SVN_NO_ERROR;
- SVN_ERR_ASSERT(editor->funcs.cb_set_target != NULL);
#ifdef ENABLE_ORDERING_CHECK
SVN_ERR_ASSERT(!editor->finished);
SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, relpath,
@@ -476,8 +486,9 @@ svn_editor_set_target(svn_editor_t *edit
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
- err = editor->funcs.cb_set_target(editor->baton, relpath, revision,
- target, editor->scratch_pool);
+ if (editor->funcs.cb_set_target)
+ err = editor->funcs.cb_set_target(editor->baton, relpath, revision,
+ target, editor->scratch_pool);
#ifdef ENABLE_ORDERING_CHECK
apr_hash_set(editor->needs_text_or_target, relpath, APR_HASH_KEY_STRING,
NULL);
@@ -495,9 +506,8 @@ svn_editor_delete(svn_editor_t *editor,
const char *relpath,
svn_revnum_t revision)
{
- svn_error_t *err;
+ svn_error_t *err = SVN_NO_ERROR;
- SVN_ERR_ASSERT(editor->funcs.cb_delete != NULL);
#ifdef ENABLE_ORDERING_CHECK
SVN_ERR_ASSERT(!editor->finished);
SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, relpath,
@@ -507,8 +517,9 @@ svn_editor_delete(svn_editor_t *editor,
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
- err = editor->funcs.cb_delete(editor->baton, relpath, revision,
- editor->scratch_pool);
+ if (editor->funcs.cb_delete)
+ err = editor->funcs.cb_delete(editor->baton, relpath, revision,
+ editor->scratch_pool);
#ifdef ENABLE_ORDERING_CHECK
apr_hash_set(editor->completed_nodes,
apr_pstrdup(editor->result_pool, relpath),
@@ -526,9 +537,8 @@ svn_editor_copy(svn_editor_t *editor,
const char *dst_relpath,
svn_revnum_t replaces_rev)
{
- svn_error_t *err;
+ svn_error_t *err = SVN_NO_ERROR;
- SVN_ERR_ASSERT(editor->funcs.cb_copy != NULL);
#ifdef ENABLE_ORDERING_CHECK
SVN_ERR_ASSERT(!editor->finished);
SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, dst_relpath,
@@ -538,9 +548,10 @@ svn_editor_copy(svn_editor_t *editor,
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
- err = editor->funcs.cb_copy(editor->baton, src_relpath, src_revision,
- dst_relpath, replaces_rev,
- editor->scratch_pool);
+ if (editor->funcs.cb_copy)
+ err = editor->funcs.cb_copy(editor->baton, src_relpath, src_revision,
+ dst_relpath, replaces_rev,
+ editor->scratch_pool);
svn_pool_clear(editor->scratch_pool);
return err;
}
@@ -553,9 +564,8 @@ svn_editor_move(svn_editor_t *editor,
const char *dst_relpath,
svn_revnum_t replaces_rev)
{
- svn_error_t *err;
+ svn_error_t *err = SVN_NO_ERROR;
- SVN_ERR_ASSERT(editor->funcs.cb_move != NULL);
#ifdef ENABLE_ORDERING_CHECK
SVN_ERR_ASSERT(!editor->finished);
SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, src_relpath,
@@ -567,9 +577,10 @@ svn_editor_move(svn_editor_t *editor,
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
- err = editor->funcs.cb_move(editor->baton, src_relpath, src_revision,
- dst_relpath, replaces_rev,
- editor->scratch_pool);
+ if (editor->funcs.cb_move)
+ err = editor->funcs.cb_move(editor->baton, src_relpath, src_revision,
+ dst_relpath, replaces_rev,
+ editor->scratch_pool);
#ifdef ENABLE_ORDERING_CHECK
/* ### after moving a node away, a new one can be created. how does
### affect the "replaces_rev" concept elsewhere? */
@@ -592,18 +603,44 @@ svn_editor_move(svn_editor_t *editor,
svn_error_t *
+svn_editor_rotate(svn_editor_t *editor,
+ const apr_array_header_t *relpaths,
+ const apr_array_header_t *revisions)
+{
+ svn_error_t *err = SVN_NO_ERROR;
+
+#ifdef ENABLE_ORDERING_CHECK
+ SVN_ERR_ASSERT(!editor->finished);
+ /* ### something more */
+#endif
+
+ if (editor->cancel_func)
+ SVN_ERR(editor->cancel_func(editor->cancel_baton));
+
+ if (editor->funcs.cb_rotate)
+ err = editor->funcs.cb_rotate(editor->baton, relpaths, revisions,
+ editor->scratch_pool);
+#ifdef ENABLE_ORDERING_CHECK
+ /* ### something more */
+#endif
+ svn_pool_clear(editor->scratch_pool);
+ return err;
+}
+
+
+svn_error_t *
svn_editor_complete(svn_editor_t *editor)
{
- svn_error_t *err;
+ svn_error_t *err = SVN_NO_ERROR;
- SVN_ERR_ASSERT(editor->funcs.cb_complete != NULL);
#ifdef ENABLE_ORDERING_CHECK
SVN_ERR_ASSERT(!editor->finished);
SVN_ERR_ASSERT(apr_hash_count(editor->pending_incomplete_children) == 0);
SVN_ERR_ASSERT(apr_hash_count(editor->needs_text_or_target) == 0);
#endif
- err = editor->funcs.cb_complete(editor->baton, editor->scratch_pool);
+ if (editor->funcs.cb_complete)
+ err = editor->funcs.cb_complete(editor->baton, editor->scratch_pool);
#ifdef ENABLE_ORDERING_CHECK
if (!err)
editor->finished = TRUE;
@@ -616,14 +653,14 @@ svn_editor_complete(svn_editor_t *editor
svn_error_t *
svn_editor_abort(svn_editor_t *editor)
{
- svn_error_t *err;
+ svn_error_t *err = SVN_NO_ERROR;
- SVN_ERR_ASSERT(editor->funcs.cb_abort != NULL);
#ifdef ENABLE_ORDERING_CHECK
SVN_ERR_ASSERT(!editor->finished);
#endif
- err = editor->funcs.cb_abort(editor->baton, editor->scratch_pool);
+ if (editor->funcs.cb_abort)
+ err = editor->funcs.cb_abort(editor->baton, editor->scratch_pool);
#ifdef ENABLE_ORDERING_CHECK
editor->finished = TRUE;
#endif
Modified: subversion/branches/moves-scan-log/subversion/libsvn_fs/fs-loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_fs/fs-loader.h?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_fs/fs-loader.h (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_fs/fs-loader.h Thu Feb 2 13:37:30 2012
@@ -25,7 +25,7 @@
#ifndef LIBSVN_FS_FS_H
#define LIBSVN_FS_FS_H
-#include "svn_version.h"
+#include "svn_types.h"
#include "svn_fs.h"
#ifdef __cplusplus
Modified: subversion/branches/moves-scan-log/subversion/libsvn_ra_neon/session.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_ra_neon/session.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_ra_neon/session.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_ra_neon/session.c Thu Feb 2 13:37:30 2012
@@ -985,12 +985,15 @@ svn_ra_neon__open(svn_ra_session_t *sess
if (authorities != NULL)
{
- char *files, *file;
- files = apr_pstrdup(pool, authorities);
+ int i;
+ apr_array_header_t *files = svn_cstring_split(authorities, ";", TRUE,
+ pool);
- while ((file = svn_cstring_tokenize(";", &files)) != NULL)
+ for (i = 0; i < files->nelts; ++i)
{
ne_ssl_certificate *ca_cert;
+ const char *file = APR_ARRAY_IDX(files, i, const char *);
+
ca_cert = ne_ssl_cert_read(file);
if (ca_cert == NULL)
{
Modified: subversion/branches/moves-scan-log/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_ra_serf/property.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_ra_serf/property.c Thu Feb 2 13:37:30 2012
@@ -988,32 +988,33 @@ svn_ra_serf__get_baseline_info(const cha
revision (if needed) with an OPTIONS request. */
if (SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session))
{
- basecoll_url = apr_psprintf(pool, "%s/%ld",
- session->rev_root_stub, revision);
+ svn_revnum_t actual_revision;
- if (latest_revnum)
+ if (SVN_IS_VALID_REVNUM(revision))
{
- if (SVN_IS_VALID_REVNUM(revision))
- {
- *latest_revnum = revision;
- }
- else
- {
- svn_ra_serf__options_context_t *opt_ctx;
+ actual_revision = revision;
+ }
+ else
+ {
+ svn_ra_serf__options_context_t *opt_ctx;
- SVN_ERR(svn_ra_serf__create_options_req(&opt_ctx, session, conn,
+ SVN_ERR(svn_ra_serf__create_options_req(&opt_ctx, session, conn,
session->session_url.path,
pool));
- SVN_ERR(svn_ra_serf__context_run_wait(
+ SVN_ERR(svn_ra_serf__context_run_wait(
svn_ra_serf__get_options_done_ptr(opt_ctx), session, pool));
- *latest_revnum = svn_ra_serf__options_get_youngest_rev(opt_ctx);
- if (! SVN_IS_VALID_REVNUM(*latest_revnum))
- return svn_error_create(SVN_ERR_RA_DAV_OPTIONS_REQ_FAILED, NULL,
- _("The OPTIONS response did not include "
- "the youngest revision"));
- }
+ actual_revision = svn_ra_serf__options_get_youngest_rev(opt_ctx);
+ if (! SVN_IS_VALID_REVNUM(actual_revision))
+ return svn_error_create(SVN_ERR_RA_DAV_OPTIONS_REQ_FAILED, NULL,
+ _("The OPTIONS response did not include "
+ "the youngest revision"));
}
+
+ basecoll_url = apr_psprintf(pool, "%s/%ld",
+ session->rev_root_stub, actual_revision);
+ if (latest_revnum)
+ *latest_revnum = actual_revision;
}
/* Otherwise, we fall back to the old VCC_URL PROPFIND hunt. */
@@ -1021,7 +1022,7 @@ svn_ra_serf__get_baseline_info(const cha
{
SVN_ERR(svn_ra_serf__discover_vcc(&vcc_url, session, conn, pool));
- if (revision != SVN_INVALID_REVNUM)
+ if (SVN_IS_VALID_REVNUM(revision))
{
/* First check baseline information cache. */
SVN_ERR(svn_ra_serf__blncache_get_bc_url(&basecoll_url,
Modified: subversion/branches/moves-scan-log/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_ra_serf/ra_serf.h?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_ra_serf/ra_serf.h Thu Feb 2 13:37:30 2012
@@ -78,6 +78,7 @@ typedef struct svn_ra_serf__connection_t
/* Are we using ssl */
svn_boolean_t using_ssl;
+ int server_cert_failures; /* Collected cert failures in chain */
/* Should we ask for compressed responses? */
svn_boolean_t using_compression;
Modified: subversion/branches/moves-scan-log/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_ra_serf/serf.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_ra_serf/serf.c Thu Feb 2 13:37:30 2012
@@ -403,6 +403,7 @@ svn_ra_serf__open(svn_ra_session_t *sess
serf_sess->conns[0]->last_status_code = -1;
serf_sess->conns[0]->using_ssl = serf_sess->using_ssl;
+ serf_sess->conns[0]->server_cert_failures = 0;
serf_sess->conns[0]->using_compression = serf_sess->using_compression;
serf_sess->conns[0]->hostname = url.hostname;
serf_sess->conns[0]->useragent = NULL;
Modified: subversion/branches/moves-scan-log/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_ra_serf/util.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_ra_serf/util.c Thu Feb 2 13:37:30 2012
@@ -271,6 +271,8 @@ ssl_server_cert(void *baton, int failure
/* Implicitly approve any non-server certs. */
if (serf_ssl_cert_depth(cert) > 0)
{
+ if (failures)
+ conn->server_cert_failures |= ssl_convert_serf_failures(failures);
return APR_SUCCESS;
}
@@ -295,7 +297,8 @@ ssl_server_cert(void *baton, int failure
cert_info.issuer_dname = convert_organisation_to_str(issuer, scratch_pool);
cert_info.ascii_cert = serf_ssl_cert_export(cert, scratch_pool);
- svn_failures = ssl_convert_serf_failures(failures);
+ svn_failures = (ssl_convert_serf_failures(failures)
+ | conn->server_cert_failures);
/* Try to find matching server name via subjectAltName first... */
if (san) {
@@ -383,20 +386,23 @@ static svn_error_t *
load_authorities(svn_ra_serf__connection_t *conn, const char *authorities,
apr_pool_t *pool)
{
- char *files, *file;
- files = apr_pstrdup(pool, authorities);
+ apr_array_header_t *files = svn_cstring_split(authorities, ";",
+ TRUE /* chop_whitespace */,
+ pool);
+ int i;
- while ((file = svn_cstring_tokenize(";", &files)) != NULL)
+ for (i = 0; i < files->nelts; ++i)
{
+ const char *file = APR_ARRAY_IDX(files, i, const char *);
serf_ssl_certificate_t *ca_cert;
apr_status_t status = serf_ssl_load_cert_file(&ca_cert, file, pool);
+
if (status == APR_SUCCESS)
status = serf_ssl_trust_cert(conn->ssl_context, ca_cert);
if (status != APR_SUCCESS)
{
- return svn_error_createf
- (SVN_ERR_BAD_CONFIG_VALUE, NULL,
+ return svn_error_createf(SVN_ERR_BAD_CONFIG_VALUE, NULL,
_("Invalid config: unable to load certificate file '%s'"),
svn_dirent_local_style(file, pool));
}
Modified: subversion/branches/moves-scan-log/subversion/libsvn_ra_svn/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_ra_svn/cyrus_auth.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_ra_svn/cyrus_auth.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_ra_svn/cyrus_auth.c Thu Feb 2 13:37:30 2012
@@ -186,12 +186,64 @@ svn_ra_svn__sasl_common_init(apr_pool_t
return SVN_NO_ERROR;
}
+/* We are going to look at errno when we get SASL_FAIL but we don't
+ know for sure whether SASL always sets errno. Clearing errno
+ before calling SASL functions helps in cases where SASL does
+ nothing to set errno. */
+#ifdef apr_set_os_error
+#define clear_sasl_errno() apr_set_os_error(APR_SUCCESS)
+#else
+#define clear_sasl_errno() (void)0
+#endif
+
+/* Sometimes SASL returns SASL_FAIL as RESULT and sets errno.
+ * SASL_FAIL translates to "generic error" which is quite unhelpful.
+ * Try to append a more informative error message based on errno so
+ * should be called before doing anything that may change errno. */
+static const char *
+get_sasl_errno_msg(int result, apr_pool_t *result_pool)
+{
+#ifdef apr_get_os_error
+ char buf[1024];
+
+ if (result == SASL_FAIL && apr_get_os_error() != 0)
+ return apr_psprintf(result_pool, ": %s",
+ svn_strerror(apr_get_os_error(), buf, sizeof(buf)));
+#endif
+ return "";
+}
+
+/* Wrap an error message from SASL with a prefix that allows users
+ * to tell that the error message came from SASL. Queries errno and
+ * so should be called before doing anything that may change errno. */
+static const char *
+get_sasl_error(sasl_conn_t *sasl_ctx, int result, apr_pool_t *result_pool)
+{
+ const char *sasl_errno_msg = get_sasl_errno_msg(result, result_pool);
+
+ return apr_psprintf(result_pool,
+ _("SASL authentication error: %s%s"),
+ sasl_errdetail(sasl_ctx), sasl_errno_msg);
+}
+
static svn_error_t *sasl_init_cb(void *baton, apr_pool_t *pool)
{
+ int result;
+
SVN_ERR(svn_ra_svn__sasl_common_init(pool));
- if (sasl_client_init(NULL) != SASL_OK)
- return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
- _("Could not initialize the SASL library"));
+ clear_sasl_errno();
+ result = sasl_client_init(NULL);
+ if (result != SASL_OK)
+ {
+ const char *sasl_errno_msg = get_sasl_errno_msg(result, pool);
+
+ return svn_error_createf
+ (SVN_ERR_RA_NOT_AUTHORIZED, NULL,
+ _("Could not initialized the SASL library: %s%s"),
+ sasl_errstring(result, NULL, NULL),
+ sasl_errno_msg);
+ }
+
return SVN_NO_ERROR;
}
@@ -338,31 +390,6 @@ get_password_cb(sasl_conn_t *conn, void
return SASL_FAIL;
}
-/* Sometimes SASL returns SASL_FAIL as RESULT and sets errno.
- * SASL_FAIL translates to "generic error" which is quite unhelpful.
- * Try to append a more informative error message based on errno. */
-static const char *
-get_sasl_errno_msg(int result, apr_pool_t *result_pool)
-{
- char buf[1024];
-
- if (result == SASL_FAIL && apr_get_os_error() != 0)
- return apr_psprintf(result_pool, ": %s",
- svn_strerror(apr_get_os_error(), buf, sizeof(buf)));
- return "";
-}
-
-/* Wrap an error message from SASL with a prefix that allows users
- * to tell that the error message came from SASL. */
-static const char *
-get_sasl_error(sasl_conn_t *sasl_ctx, int result, apr_pool_t *result_pool)
-{
- return apr_psprintf(result_pool,
- _("SASL authentication error: %s%s"),
- sasl_errdetail(sasl_ctx),
- get_sasl_errno_msg(result, result_pool));
-}
-
/* Create a new SASL context. */
static svn_error_t *new_sasl_ctx(sasl_conn_t **sasl_ctx,
svn_boolean_t is_tunneled,
@@ -375,15 +402,20 @@ static svn_error_t *new_sasl_ctx(sasl_co
sasl_security_properties_t secprops;
int result;
+ clear_sasl_errno();
result = sasl_client_new(SVN_RA_SVN_SASL_NAME,
hostname, local_addrport, remote_addrport,
callbacks, SASL_SUCCESS_DATA,
sasl_ctx);
if (result != SASL_OK)
- return svn_error_createf(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
- _("Could not create SASL context: %s%s"),
- sasl_errstring(result, NULL, NULL),
- get_sasl_errno_msg(result, pool));
+ {
+ const char *sasl_errno_msg = get_sasl_errno_msg(result, pool);
+
+ return svn_error_createf(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
+ _("Could not create SASL context: %s%s"),
+ sasl_errstring(result, NULL, NULL),
+ sasl_errno_msg);
+ }
svn_atomic_inc(&sasl_ctx_count);
apr_pool_cleanup_register(pool, *sasl_ctx, sasl_dispose_cb,
apr_pool_cleanup_null);
@@ -394,6 +426,7 @@ static svn_error_t *new_sasl_ctx(sasl_co
otherwise it will ignore EXTERNAL. The third parameter
should be the username, but since SASL doesn't seem
to use it on the client side, any non-empty string will do. */
+ clear_sasl_errno();
result = sasl_setprop(*sasl_ctx,
SASL_AUTH_EXTERNAL, " ");
if (result != SASL_OK)
@@ -426,6 +459,7 @@ static svn_error_t *try_auth(svn_ra_svn_
do
{
again = FALSE;
+ clear_sasl_errno();
result = sasl_client_start(sasl_ctx,
mechstring,
&client_interact,
@@ -496,6 +530,7 @@ static svn_error_t *try_auth(svn_ra_svn_
if (strcmp(mech, "CRAM-MD5") != 0)
in = svn_base64_decode_string(in, pool);
+ clear_sasl_errno();
result = sasl_client_step(sasl_ctx,
in->data,
in->len,
@@ -584,6 +619,7 @@ static svn_error_t *sasl_read_cb(void *b
*len = 0;
return SVN_NO_ERROR;
}
+ clear_sasl_errno();
result = sasl_decode(sasl_baton->ctx, buffer, len2,
&sasl_baton->read_buf,
&sasl_baton->read_len);
@@ -625,6 +661,7 @@ sasl_write_cb(void *baton, const char *b
{
/* Make sure we don't write too much. */
*len = (*len > sasl_baton->maxsize) ? sasl_baton->maxsize : *len;
+ clear_sasl_errno();
result = sasl_encode(sasl_baton->ctx, buffer, *len,
&sasl_baton->write_buf,
&sasl_baton->write_len);
@@ -685,6 +722,7 @@ svn_error_t *svn_ra_svn__enable_sasl_enc
int result;
/* Get the strength of the security layer. */
+ clear_sasl_errno();
result = sasl_getprop(sasl_ctx, SASL_SSF, (void*) &ssfp);
if (result != SASL_OK)
return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
@@ -704,6 +742,7 @@ svn_error_t *svn_ra_svn__enable_sasl_enc
sasl_baton->scratch_pool = conn->pool;
/* Find out the maximum input size for sasl_encode. */
+ clear_sasl_errno();
result = sasl_getprop(sasl_ctx, SASL_MAXOUTBUF, &maxsize);
if (result != SASL_OK)
return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
@@ -714,6 +753,7 @@ svn_error_t *svn_ra_svn__enable_sasl_enc
we need to decrypt it. */
if (conn->read_end > conn->read_ptr)
{
+ clear_sasl_errno();
result = sasl_decode(sasl_ctx, conn->read_ptr,
conn->read_end - conn->read_ptr,
&sasl_baton->read_buf,
Modified: subversion/branches/moves-scan-log/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_repos/commit.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_repos/commit.c Thu Feb 2 13:37:30 2012
@@ -823,6 +823,7 @@ kind_fetch_func(svn_kind_t *kind,
{
struct edit_baton *eb = baton;
svn_node_kind_t node_kind;
+ svn_fs_root_t *fs_root;
if (!SVN_IS_VALID_REVNUM(base_revision))
base_revision = svn_fs_txn_base_revision(eb->txn);
@@ -831,6 +832,7 @@ kind_fetch_func(svn_kind_t *kind,
{
/* This is a copyfrom URL. */
path = svn_uri_skip_ancestor(eb->repos_url, path, scratch_pool);
+ path = svn_fspath__canonicalize(path, scratch_pool);
}
else
{
@@ -840,7 +842,9 @@ kind_fetch_func(svn_kind_t *kind,
path = svn_fspath__join(eb->base_path, path, scratch_pool);
}
- SVN_ERR(svn_fs_check_path(&node_kind, eb->txn_root, path, scratch_pool));
+ SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));
+
+ SVN_ERR(svn_fs_check_path(&node_kind, fs_root, path, scratch_pool));
*kind = svn__kind_from_node_kind(node_kind, FALSE);
return SVN_NO_ERROR;
@@ -868,6 +872,7 @@ fetch_base_func(const char **filename,
{
/* This is a copyfrom URL. */
path = svn_uri_skip_ancestor(eb->repos_url, path, scratch_pool);
+ path = svn_fspath__canonicalize(path, scratch_pool);
}
else
{
Modified: subversion/branches/moves-scan-log/subversion/libsvn_repos/load-fs-vtable.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_repos/load-fs-vtable.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_repos/load-fs-vtable.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_repos/load-fs-vtable.c Thu Feb 2 13:37:30 2012
@@ -160,12 +160,12 @@ change_rev_prop(svn_repos_t *repos,
apr_pool_t *pool)
{
if (validate_props)
- return svn_fs_change_rev_prop2(svn_repos_fs(repos), revision, name,
- NULL, value, pool);
- else
return svn_repos_fs_change_rev_prop4(repos, revision, NULL, name,
NULL, value, FALSE, FALSE,
NULL, NULL, pool);
+ else
+ return svn_fs_change_rev_prop2(svn_repos_fs(repos), revision, name,
+ NULL, value, pool);
}
/* Change property NAME to VALUE for PATH in TXN_ROOT. If
Modified: subversion/branches/moves-scan-log/subversion/libsvn_subr/cmdline.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_subr/cmdline.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_subr/cmdline.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_subr/cmdline.c Thu Feb 2 13:37:30 2012
@@ -226,7 +226,7 @@ svn_cmdline_init(const char *progname, F
/* Create a pool for use by the UTF-8 routines. It will be cleaned
up by APR at exit time. */
pool = svn_pool_create(NULL);
- svn_utf_initialize(pool);
+ svn_utf_initialize2(pool, FALSE);
if ((err = svn_nls_init()))
{
Modified: subversion/branches/moves-scan-log/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_subr/config_file.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_subr/config_file.c Thu Feb 2 13:37:30 2012
@@ -1050,7 +1050,7 @@ svn_config_ensure(const char *config_dir
"### path separator. A single backslash will be treated as an" NL
"### escape for the following character." NL
"" NL
- "### Section for configuring miscelleneous Subversion options." NL
+ "### Section for configuring miscellaneous Subversion options." NL
"[miscellany]" NL
"### Set global-ignores to a set of whitespace-delimited globs" NL
"### which Subversion will ignore in its 'status' output, and" NL
Modified: subversion/branches/moves-scan-log/subversion/libsvn_subr/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_subr/deprecated.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_subr/deprecated.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_subr/deprecated.c Thu Feb 2 13:37:30 2012
@@ -39,6 +39,7 @@
#include "svn_pools.h"
#include "svn_dso.h"
#include "svn_mergeinfo.h"
+#include "svn_utf.h"
#include "svn_xml.h"
#include "opt.h"
@@ -1173,3 +1174,9 @@ svn_xml_make_header(svn_stringbuf_t **st
{
svn_xml_make_header2(str, NULL, pool);
}
+
+void
+svn_utf_initialize(apr_pool_t *pool)
+{
+ svn_utf_initialize2(pool, FALSE);
+}
Modified: subversion/branches/moves-scan-log/subversion/libsvn_subr/spillbuf.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_subr/spillbuf.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_subr/spillbuf.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_subr/spillbuf.c Thu Feb 2 13:37:30 2012
@@ -552,3 +552,56 @@ svn_spillbuf__reader_write(svn_spillbuf_
return svn_error_trace(svn_spillbuf__write(&reader->buf, data, len,
scratch_pool));
}
+
+
+struct spillbuf_baton
+{
+ svn_spillbuf_reader_t *reader;
+ apr_pool_t *scratch_pool;
+};
+
+
+static svn_error_t *
+read_handler_spillbuf(void *baton, char *buffer, apr_size_t *len)
+{
+ struct spillbuf_baton *sb = baton;
+
+ SVN_ERR(svn_spillbuf__reader_read(len, sb->reader, buffer, *len,
+ sb->scratch_pool));
+
+ svn_pool_clear(sb->scratch_pool);
+ return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
+write_handler_spillbuf(void *baton, const char *data, apr_size_t *len)
+{
+ struct spillbuf_baton *sb = baton;
+
+ SVN_ERR(svn_spillbuf__reader_write(sb->reader, data, *len, sb->scratch_pool));
+
+ svn_pool_clear(sb->scratch_pool);
+ return SVN_NO_ERROR;
+}
+
+
+svn_stream_t *
+svn_stream__from_spillbuf(apr_size_t blocksize,
+ apr_size_t maxsize,
+ apr_pool_t *result_pool)
+{
+ svn_stream_t *stream;
+ struct spillbuf_baton *sb = apr_pcalloc(result_pool, sizeof(*sb));
+
+ sb->reader = svn_spillbuf__reader_create(blocksize, maxsize, result_pool);
+ sb->scratch_pool = svn_pool_create(result_pool);
+
+ stream = svn_stream_create(sb, result_pool);
+
+ svn_stream_set_read(stream, read_handler_spillbuf);
+ svn_stream_set_write(stream, write_handler_spillbuf);
+
+
+ return stream;
+}
Modified: subversion/branches/moves-scan-log/subversion/libsvn_subr/ssl_server_trust_providers.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_subr/ssl_server_trust_providers.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_subr/ssl_server_trust_providers.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_subr/ssl_server_trust_providers.c Thu Feb 2 13:37:30 2012
@@ -208,11 +208,12 @@ ssl_server_trust_prompt_first_cred(void
apr_hash_get(parameters,
SVN_AUTH_PARAM_SSL_SERVER_CERT_INFO,
APR_HASH_KEY_STRING);
+ svn_boolean_t may_save = (!no_auth_cache
+ && !(*failures & SVN_AUTH_SSL_OTHER));
- SVN_ERR(pb->prompt_func((svn_auth_cred_ssl_server_trust_t **)
- credentials_p, pb->prompt_baton, realmstring,
- *failures, cert_info, ! no_auth_cache &&
- ! (*failures & SVN_AUTH_SSL_OTHER), pool));
+ SVN_ERR(pb->prompt_func((svn_auth_cred_ssl_server_trust_t **)credentials_p,
+ pb->prompt_baton, realmstring, *failures, cert_info,
+ may_save, pool));
*iter_baton = NULL;
return SVN_NO_ERROR;
Modified: subversion/branches/moves-scan-log/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_subr/stream.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_subr/stream.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_subr/stream.c Thu Feb 2 13:37:30 2012
@@ -45,6 +45,7 @@
#include "private/svn_error_private.h"
#include "private/svn_eol_private.h"
#include "private/svn_io_private.h"
+#include "private/svn_subr_private.h"
struct svn_stream_t {
@@ -1642,3 +1643,16 @@ svn_string_from_stream(svn_string_t **re
return SVN_NO_ERROR;
}
+
+
+/* These are somewhat arbirary, if we ever get good empirical data as to
+ actually valid values, feel free to update them. */
+#define BUFFER_BLOCK_SIZE 1024
+#define BUFFER_MAX_SIZE 100000
+
+svn_stream_t *
+svn_stream_buffered(apr_pool_t *result_pool)
+{
+ return svn_stream__from_spillbuf(BUFFER_BLOCK_SIZE, BUFFER_MAX_SIZE,
+ result_pool);
+}
Modified: subversion/branches/moves-scan-log/subversion/libsvn_subr/utf.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_subr/utf.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_subr/utf.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_subr/utf.c Thu Feb 2 13:37:30 2012
@@ -23,6 +23,7 @@
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
@@ -55,6 +56,7 @@ static const char *SVN_UTF_UTON_XLATE_HA
static const char *SVN_APR_UTF8_CHARSET = "UTF-8";
static svn_mutex__t *xlate_handle_mutex = NULL;
+static svn_boolean_t assume_native_charset_is_utf8 = FALSE;
/* The xlate handle cache is a global hash table with linked lists of xlate
* handles. In multi-threaded environments, a thread "borrows" an xlate
@@ -118,7 +120,8 @@ xlate_handle_node_cleanup(void *arg)
}
void
-svn_utf_initialize(apr_pool_t *pool)
+svn_utf_initialize2(apr_pool_t *pool,
+ svn_boolean_t assume_native_utf8)
{
if (!xlate_handle_hash)
{
@@ -141,6 +144,9 @@ svn_utf_initialize(apr_pool_t *pool)
apr_pool_cleanup_register(subpool, NULL, xlate_cleanup,
apr_pool_cleanup_null);
}
+
+ if (!assume_native_charset_is_utf8)
+ assume_native_charset_is_utf8 = assume_native_utf8;
}
/* Return a unique string key based on TOPAGE and FROMPAGE. TOPAGE and
@@ -442,7 +448,9 @@ static svn_error_t *
get_ntou_xlate_handle_node(xlate_handle_node_t **ret, apr_pool_t *pool)
{
return get_xlate_handle_node(ret, SVN_APR_UTF8_CHARSET,
- SVN_APR_LOCALE_CHARSET,
+ assume_native_charset_is_utf8
+ ? SVN_APR_UTF8_CHARSET
+ : SVN_APR_LOCALE_CHARSET,
SVN_UTF_NTOU_XLATE_HANDLE, pool);
}
@@ -455,7 +463,10 @@ get_ntou_xlate_handle_node(xlate_handle_
static svn_error_t *
get_uton_xlate_handle_node(xlate_handle_node_t **ret, apr_pool_t *pool)
{
- return get_xlate_handle_node(ret, SVN_APR_LOCALE_CHARSET,
+ return get_xlate_handle_node(ret,
+ assume_native_charset_is_utf8
+ ? SVN_APR_UTF8_CHARSET
+ : SVN_APR_LOCALE_CHARSET,
SVN_APR_UTF8_CHARSET,
SVN_UTF_UTON_XLATE_HANDLE, pool);
}
Modified: subversion/branches/moves-scan-log/subversion/libsvn_wc/diff_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_wc/diff_editor.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_wc/diff_editor.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_wc/diff_editor.c Thu Feb 2 13:37:30 2012
@@ -1937,7 +1937,7 @@ svn_wc_get_diff_editor6(const svn_delta_
sfb = apr_palloc(result_pool, sizeof(*sfb));
sfb->db = wc_ctx->db;
sfb->base_abspath = eb->anchor_abspath;
- sfb->fetch_base = FALSE;
+ sfb->fetch_base = TRUE;
shim_callbacks->fetch_kind_func = svn_wc__fetch_kind_func;
shim_callbacks->fetch_props_func = svn_wc__fetch_props_func;
Modified: subversion/branches/moves-scan-log/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_wc/status.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_wc/status.c Thu Feb 2 13:37:30 2012
@@ -2610,7 +2610,11 @@ svn_wc__internal_walk_status(svn_wc__db_
SVN_ERR(svn_io_stat_dirent(&dirent, local_abspath, TRUE,
scratch_pool, scratch_pool));
- if (info && info->kind == svn_kind_dir)
+ if (info
+ && info->kind == svn_kind_dir
+ && info->status != svn_wc__db_status_not_present
+ && info->status != svn_wc__db_status_excluded
+ && info->status != svn_wc__db_status_server_excluded)
{
SVN_ERR(get_dir_status(&wb,
local_abspath,
Modified: subversion/branches/moves-scan-log/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_wc/update_editor.c?rev=1239613&r1=1239612&r2=1239613&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_wc/update_editor.c Thu Feb 2 13:37:30 2012
@@ -5080,47 +5080,6 @@ close_edit(void *edit_baton,
return SVN_NO_ERROR;
}
-
-static svn_error_t *
-fetch_props_func(apr_hash_t **props,
- void *baton,
- const char *path,
- svn_revnum_t base_revision,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- struct svn_wc__shim_fetch_baton_t *sfb = baton;
- const char *local_abspath = svn_dirent_join(sfb->base_abspath, path,
- scratch_pool);
- svn_error_t *err;
-
- if (sfb->fetch_base)
- err = svn_wc__db_base_get_props(props, sfb->db, local_abspath, result_pool,
- scratch_pool);
- else
- err = svn_wc__db_read_props(props, sfb->db, local_abspath,
- result_pool, scratch_pool);
-
- /* If the path doesn't exist, just return an empty set of props. */
- if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
- {
- svn_error_clear(err);
- *props = apr_hash_make(result_pool);
- }
- else if (err)
- return svn_error_trace(err);
-
- /* Add a bogus LOCK_TOKEN if we don't already have one, so as to catch
- any deletions thereto. */
- if (!apr_hash_get(*props, SVN_PROP_ENTRY_LOCK_TOKEN, APR_HASH_KEY_STRING))
- {
- apr_hash_set(*props, SVN_PROP_ENTRY_LOCK_TOKEN, APR_HASH_KEY_STRING,
- svn_string_create("This is completely bogus", result_pool));
- }
-
- return SVN_NO_ERROR;
-}
-
/*** Returning editors. ***/
@@ -5402,7 +5361,7 @@ make_editor(svn_revnum_t *target_revisio
sfb->fetch_base = TRUE;
shim_callbacks->fetch_kind_func = svn_wc__fetch_kind_func;
- shim_callbacks->fetch_props_func = fetch_props_func;
+ shim_callbacks->fetch_props_func = svn_wc__fetch_props_func;
shim_callbacks->fetch_base_func = svn_wc__fetch_base_func;
shim_callbacks->fetch_baton = sfb;