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 2013/10/15 10:52:18 UTC
svn commit: r1532250 [12/37] - in /subversion/branches/cache-server: ./
build/ build/ac-macros/ build/generator/ build/generator/swig/
build/generator/templates/ contrib/client-side/emacs/ contrib/hook-scripts/
contrib/server-side/fsfsfixer/ contrib/se...
Modified: subversion/branches/cache-server/subversion/libsvn_client/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/mergeinfo.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/mergeinfo.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/mergeinfo.c Tue Oct 15 08:52:06 2013
@@ -24,6 +24,7 @@
#include <apr_pools.h>
#include <apr_strings.h>
+#include "svn_private_config.h"
#include "svn_pools.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
@@ -46,7 +47,6 @@
#include "private/svn_client_private.h"
#include "client.h"
#include "mergeinfo.h"
-#include "svn_private_config.h"
@@ -1021,6 +1021,11 @@ svn_client__elide_mergeinfo(const char *
Set *REPOS_ROOT to the root URL of the repository associated with
PATH_OR_URL.
+ If RA_SESSION is NOT NULL and PATH_OR_URL refers to a URL, RA_SESSION
+ (which must be of the repository containing PATH_OR_URL) will be used
+ instead of a temporary RA session. Caller is responsible for reparenting
+ the session if it wants to use it after the call.
+
Allocate *MERGEINFO_CATALOG and all its contents in RESULT_POOL. Use
SCRATCH_POOL for all temporary allocations.
@@ -1034,17 +1039,30 @@ get_mergeinfo(svn_mergeinfo_catalog_t *m
svn_boolean_t include_descendants,
svn_boolean_t ignore_invalid_mergeinfo,
svn_client_ctx_t *ctx,
+ svn_ra_session_t *ra_session,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- svn_ra_session_t *ra_session;
const char *local_abspath;
svn_boolean_t use_url = svn_path_is_url(path_or_url);
svn_client__pathrev_t *peg_loc;
- SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &peg_loc,
- path_or_url, NULL, peg_revision,
- peg_revision, ctx, scratch_pool));
+ if (ra_session && svn_path_is_url(path_or_url))
+ {
+ SVN_ERR(svn_ra_reparent(ra_session, path_or_url, scratch_pool));
+ SVN_ERR(svn_client__resolve_rev_and_url(&peg_loc, ra_session,
+ path_or_url,
+ peg_revision,
+ peg_revision,
+ ctx, scratch_pool));
+ }
+ else
+ {
+ SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &peg_loc,
+ path_or_url, NULL,
+ peg_revision,
+ peg_revision, ctx, scratch_pool));
+ }
/* If PATH_OR_URL is as working copy path determine if we will need to
contact the repository for the requested PEG_REVISION. */
@@ -1064,10 +1082,6 @@ get_mergeinfo(svn_mergeinfo_catalog_t *m
}
}
- /* Check server Merge Tracking capability. */
- SVN_ERR(svn_ra__assert_mergeinfo_capable_server(ra_session, path_or_url,
- scratch_pool));
-
SVN_ERR(svn_ra_get_repos_root2(ra_session, repos_root, result_pool));
if (use_url)
@@ -1391,17 +1405,21 @@ filter_log_entry_with_rangelist(void *ba
obviously back. If it was added or replaced it's still around
possibly it was replaced one or more times, but it's back now.
Regardless, LOG_ENTRY->REVISION is *not* an eligible revision! */
- if (ancestor_is_self /* Explicit mergeinfo on TARGET_PATH_AFFECTED */
+ if (nearest_ancestor_mergeinfo &&
+ ancestor_is_self /* Explicit mergeinfo on TARGET_PATH_AFFECTED */
&& (change->action != 'M'))
{
svn_rangelist_t *rangelist =
svn_hash_gets(nearest_ancestor_mergeinfo, path);
- svn_merge_range_t *youngest_range = APR_ARRAY_IDX(
- rangelist, rangelist->nelts - 1, svn_merge_range_t *);
+ if (rangelist)
+ {
+ svn_merge_range_t *youngest_range = APR_ARRAY_IDX(
+ rangelist, rangelist->nelts - 1, svn_merge_range_t *);
- if (youngest_range
- && (youngest_range->end > log_entry->revision))
- continue;
+ if (youngest_range
+ && (youngest_range->end > log_entry->revision))
+ continue;
+ }
}
if (nearest_ancestor_mergeinfo)
@@ -1496,29 +1514,22 @@ logs_for_mergeinfo_rangelist(const char
svn_log_entry_receiver_t log_receiver,
void *log_receiver_baton,
svn_client_ctx_t *ctx,
+ svn_ra_session_t *ra_session,
apr_pool_t *scratch_pool)
{
- apr_array_header_t *target;
svn_merge_range_t *oldest_range, *youngest_range;
- apr_array_header_t *revision_ranges;
- svn_opt_revision_t oldest_rev, youngest_rev;
+ svn_revnum_t oldest_rev, youngest_rev;
struct filter_log_entry_baton_t fleb;
if (! rangelist->nelts)
return SVN_NO_ERROR;
- /* Build a single-member log target list using SOURCE_URL. */
- target = apr_array_make(scratch_pool, 1, sizeof(const char *));
- APR_ARRAY_PUSH(target, const char *) = source_url;
-
/* Calculate and construct the bounds of our log request. */
youngest_range = APR_ARRAY_IDX(rangelist, rangelist->nelts - 1,
svn_merge_range_t *);
- youngest_rev.kind = svn_opt_revision_number;
- youngest_rev.value.number = youngest_range->end;
+ youngest_rev = youngest_range->end;
oldest_range = APR_ARRAY_IDX(rangelist, 0, svn_merge_range_t *);
- oldest_rev.kind = svn_opt_revision_number;
- oldest_rev.value.number = oldest_range->start;
+ oldest_rev = oldest_range->start;
if (! target_mergeinfo_catalog)
target_mergeinfo_catalog = apr_hash_make(scratch_pool);
@@ -1543,19 +1554,29 @@ logs_for_mergeinfo_rangelist(const char
fleb.log_receiver_baton = log_receiver_baton;
fleb.ctx = ctx;
- /* Drive the log. */
- revision_ranges = apr_array_make(scratch_pool, 1,
- sizeof(svn_opt_revision_range_t *));
- if (oldest_revs_first)
- APR_ARRAY_PUSH(revision_ranges, svn_opt_revision_range_t *)
- = svn_opt__revision_range_create(&oldest_rev, &youngest_rev, scratch_pool);
+ if (!ra_session)
+ SVN_ERR(svn_client__open_ra_session_internal(&ra_session, NULL, source_url,
+ NULL, NULL, FALSE, FALSE, ctx,
+ scratch_pool, scratch_pool));
else
- APR_ARRAY_PUSH(revision_ranges, svn_opt_revision_range_t *)
- = svn_opt__revision_range_create(&youngest_rev, &oldest_rev, scratch_pool);
- SVN_ERR(svn_client_log5(target, &youngest_rev, revision_ranges,
- 0, discover_changed_paths, FALSE, FALSE, revprops,
- filter_log_entry_with_rangelist, &fleb, ctx,
- scratch_pool));
+ SVN_ERR(svn_ra_reparent(ra_session, source_url, scratch_pool));
+
+ {
+ apr_array_header_t *target;
+ target = apr_array_make(scratch_pool, 1, sizeof(const char *));
+ APR_ARRAY_PUSH(target, const char *) = "";
+
+ SVN_ERR(svn_ra_get_log2(ra_session, target,
+ oldest_revs_first ? oldest_rev : youngest_rev,
+ oldest_revs_first ? youngest_rev : oldest_rev,
+ 0 /* limit */,
+ discover_changed_paths,
+ FALSE /* strict_node_history */,
+ FALSE /* include_merged_revisions */,
+ revprops,
+ filter_log_entry_with_rangelist, &fleb,
+ scratch_pool));
+ }
/* Check for cancellation. */
if (ctx->cancel_func)
@@ -1616,7 +1637,7 @@ svn_client_mergeinfo_get_merged(apr_hash
svn_mergeinfo_t mergeinfo;
SVN_ERR(get_mergeinfo(&mergeinfo_cat, &repos_root, path_or_url,
- peg_revision, FALSE, FALSE, ctx, pool, pool));
+ peg_revision, FALSE, FALSE, ctx, NULL, pool, pool));
if (mergeinfo_cat)
{
const char *repos_relpath;
@@ -1647,11 +1668,11 @@ svn_client_mergeinfo_get_merged(apr_hash
return SVN_NO_ERROR;
}
-
svn_error_t *
-svn_client_mergeinfo_log2(svn_boolean_t finding_merged,
+svn_client__mergeinfo_log(svn_boolean_t finding_merged,
const char *target_path_or_url,
const svn_opt_revision_t *target_peg_revision,
+ svn_mergeinfo_catalog_t *target_mergeinfo_catalog,
const char *source_path_or_url,
const svn_opt_revision_t *source_peg_revision,
const svn_opt_revision_t *source_start_revision,
@@ -1662,12 +1683,16 @@ svn_client_mergeinfo_log2(svn_boolean_t
svn_depth_t depth,
const apr_array_header_t *revprops,
svn_client_ctx_t *ctx,
+ svn_ra_session_t *ra_session,
+ apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
const char *log_target = NULL;
const char *repos_root;
const char *target_repos_relpath;
svn_mergeinfo_catalog_t target_mergeinfo_cat;
+ svn_ra_session_t *target_session = NULL;
+ svn_client__pathrev_t *pathrev;
/* A hash of paths, at or under TARGET_PATH_OR_URL, mapped to
rangelists. Not technically mergeinfo, so not using the
@@ -1684,6 +1709,7 @@ svn_client_mergeinfo_log2(svn_boolean_t
apr_hash_index_t *hi;
apr_pool_t *iterpool;
svn_boolean_t oldest_revs_first = TRUE;
+ apr_pool_t *subpool;
/* We currently only support depth = empty | infinity. */
if (depth != svn_depth_infinity && depth != svn_depth_empty)
@@ -1709,6 +1735,11 @@ svn_client_mergeinfo_log2(svn_boolean_t
&& (source_start_revision->kind != svn_opt_revision_unspecified))
return svn_error_create(SVN_ERR_CLIENT_BAD_REVISION, NULL, NULL);
+ subpool = svn_pool_create(scratch_pool);
+
+ if (ra_session)
+ target_session = ra_session;
+
/* We need the union of TARGET_PATH_OR_URL@TARGET_PEG_REVISION's mergeinfo
and MERGE_SOURCE_URL's history. It's not enough to do path
matching, because renames in the history of MERGE_SOURCE_URL
@@ -1716,10 +1747,61 @@ svn_client_mergeinfo_log2(svn_boolean_t
the target, that vastly simplifies matters (we'll have nothing to
do). */
/* This get_mergeinfo() call doubles as a mergeinfo capabilities check. */
- SVN_ERR(get_mergeinfo(&target_mergeinfo_cat, &repos_root,
- target_path_or_url, target_peg_revision,
- depth == svn_depth_infinity, TRUE,
- ctx, scratch_pool, scratch_pool));
+ if (target_mergeinfo_catalog)
+ {
+ if (*target_mergeinfo_catalog)
+ {
+ /* The caller provided the mergeinfo catalog for
+ TARGET_PATH_OR_URL, so we don't need to accquire
+ it ourselves. We do need to get the repos_root
+ though, because get_mergeinfo() won't do it for us. */
+ target_mergeinfo_cat = *target_mergeinfo_catalog;
+
+ if (ra_session && svn_path_is_url(target_path_or_url))
+ {
+ SVN_ERR(svn_ra_reparent(ra_session, target_path_or_url, subpool));
+ SVN_ERR(svn_client__resolve_rev_and_url(&pathrev, ra_session,
+ target_path_or_url,
+ target_peg_revision,
+ target_peg_revision,
+ ctx, subpool));
+ target_session = ra_session;
+ }
+ else
+ {
+ SVN_ERR(svn_client__ra_session_from_path2(&target_session,
+ &pathrev,
+ target_path_or_url,
+ NULL,
+ target_peg_revision,
+ target_peg_revision,
+ ctx, subpool));
+ }
+ SVN_ERR(svn_ra_get_repos_root2(target_session, &repos_root,
+ scratch_pool));
+ }
+ else
+ {
+ /* The caller didn't provide the mergeinfo catalog for
+ TARGET_PATH_OR_URL, but wants us to pass a copy back
+ when we get it, so use RESULT_POOL. */
+ SVN_ERR(get_mergeinfo(target_mergeinfo_catalog, &repos_root,
+ target_path_or_url, target_peg_revision,
+ depth == svn_depth_infinity, TRUE,
+ ctx, ra_session, result_pool, scratch_pool));
+ target_mergeinfo_cat = *target_mergeinfo_catalog;
+ }
+ }
+ else
+ {
+ /* The caller didn't provide the mergeinfo catalog for
+ TARGET_PATH_OR_URL, nor does it want a copy, so we can use
+ nothing but SCRATCH_POOL. */
+ SVN_ERR(get_mergeinfo(&target_mergeinfo_cat, &repos_root,
+ target_path_or_url, target_peg_revision,
+ depth == svn_depth_infinity, TRUE,
+ ctx, ra_session, scratch_pool, scratch_pool));
+ }
if (!svn_path_is_url(target_path_or_url))
{
@@ -1751,6 +1833,7 @@ svn_client_mergeinfo_log2(svn_boolean_t
history. */
if (finding_merged)
{
+ svn_pool_destroy(subpool);
return SVN_NO_ERROR;
}
else
@@ -1768,18 +1851,17 @@ svn_client_mergeinfo_log2(svn_boolean_t
* ### TODO: As the source and target must be in the same repository, we
* should share a single session, tracking the two URLs separately. */
{
- apr_pool_t *sesspool = svn_pool_create(scratch_pool);
- svn_ra_session_t *source_session, *target_session;
- svn_client__pathrev_t *pathrev;
+ svn_ra_session_t *source_session;
svn_revnum_t start_rev, end_rev, youngest_rev = SVN_INVALID_REVNUM;
if (! finding_merged)
{
- SVN_ERR(svn_client__ra_session_from_path2(&target_session, &pathrev,
- target_path_or_url, NULL,
- target_peg_revision,
- target_peg_revision,
- ctx, sesspool));
+ if (!target_session)
+ SVN_ERR(svn_client__ra_session_from_path2(&target_session, &pathrev,
+ target_path_or_url, NULL,
+ target_peg_revision,
+ target_peg_revision,
+ ctx, subpool));
SVN_ERR(svn_client__get_history_as_mergeinfo(&target_history, NULL,
pathrev,
SVN_INVALID_REVNUM,
@@ -1788,21 +1870,38 @@ svn_client_mergeinfo_log2(svn_boolean_t
scratch_pool));
}
- SVN_ERR(svn_client__ra_session_from_path2(&source_session, &pathrev,
- source_path_or_url, NULL,
- source_peg_revision,
- source_peg_revision,
- ctx, sesspool));
+ if (target_session
+ && svn_path_is_url(source_path_or_url)
+ && repos_root
+ && svn_uri_skip_ancestor(repos_root, source_path_or_url, subpool))
+ {
+ /* We can re-use the existing session */
+ source_session = target_session;
+ SVN_ERR(svn_ra_reparent(source_session, source_path_or_url, subpool));
+ SVN_ERR(svn_client__resolve_rev_and_url(&pathrev, source_session,
+ source_path_or_url,
+ source_peg_revision,
+ source_peg_revision,
+ ctx, subpool));
+ }
+ else
+ {
+ SVN_ERR(svn_client__ra_session_from_path2(&source_session, &pathrev,
+ source_path_or_url, NULL,
+ source_peg_revision,
+ source_peg_revision,
+ ctx, subpool));
+ }
SVN_ERR(svn_client__get_revision_number(&start_rev, &youngest_rev,
ctx->wc_ctx, source_path_or_url,
source_session,
source_start_revision,
- sesspool));
+ subpool));
SVN_ERR(svn_client__get_revision_number(&end_rev, &youngest_rev,
ctx->wc_ctx, source_path_or_url,
source_session,
source_end_revision,
- sesspool));
+ subpool));
SVN_ERR(svn_client__get_history_as_mergeinfo(&source_history, NULL,
pathrev,
MAX(end_rev, start_rev),
@@ -1811,9 +1910,6 @@ svn_client_mergeinfo_log2(svn_boolean_t
scratch_pool));
if (start_rev > end_rev)
oldest_revs_first = FALSE;
-
- /* Close the source and target sessions. */
- svn_pool_destroy(sesspool);
}
/* Separate the explicit or inherited mergeinfo on TARGET_PATH_OR_URL,
@@ -2070,7 +2166,10 @@ svn_client_mergeinfo_log2(svn_boolean_t
log_target = svn_path_url_add_component2(repos_root, log_target + 1,
scratch_pool);
- SVN_ERR(logs_for_mergeinfo_rangelist(log_target, merge_source_fspaths,
+ {
+ svn_error_t *err;
+
+ err = logs_for_mergeinfo_rangelist(log_target, merge_source_fspaths,
finding_merged,
master_inheritable_rangelist,
oldest_revs_first,
@@ -2081,8 +2180,40 @@ svn_client_mergeinfo_log2(svn_boolean_t
discover_changed_paths,
revprops,
log_receiver, log_receiver_baton,
- ctx, scratch_pool));
- return SVN_NO_ERROR;
+ ctx, target_session, scratch_pool);
+
+ /* Close the source and target sessions. */
+ svn_pool_destroy(subpool); /* For SVN_ERR_CEASE_INVOCATION */
+
+ return svn_error_trace(err);
+ }
+}
+
+svn_error_t *
+svn_client_mergeinfo_log2(svn_boolean_t finding_merged,
+ const char *target_path_or_url,
+ const svn_opt_revision_t *target_peg_revision,
+ const char *source_path_or_url,
+ const svn_opt_revision_t *source_peg_revision,
+ const svn_opt_revision_t *source_start_revision,
+ const svn_opt_revision_t *source_end_revision,
+ svn_log_entry_receiver_t log_receiver,
+ void *log_receiver_baton,
+ svn_boolean_t discover_changed_paths,
+ svn_depth_t depth,
+ const apr_array_header_t *revprops,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ return svn_error_trace(
+ svn_client__mergeinfo_log(finding_merged, target_path_or_url,
+ target_peg_revision, NULL,
+ source_path_or_url, source_peg_revision,
+ source_start_revision, source_end_revision,
+ log_receiver, log_receiver_baton,
+ discover_changed_paths, depth, revprops,
+ ctx, NULL,
+ scratch_pool, scratch_pool));
}
svn_error_t *
@@ -2120,7 +2251,7 @@ svn_client_suggest_merge_sources(apr_arr
/* ### TODO: Share ra_session batons to improve efficiency? */
SVN_ERR(get_mergeinfo(&mergeinfo_cat, &repos_root, path_or_url,
- peg_revision, FALSE, FALSE, ctx, pool, pool));
+ peg_revision, FALSE, FALSE, ctx, NULL, pool, pool));
if (mergeinfo_cat && apr_hash_count(mergeinfo_cat))
{
Modified: subversion/branches/cache-server/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/patch.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/patch.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/patch.c Tue Oct 15 08:52:06 2013
@@ -29,6 +29,8 @@
#include <apr_hash.h>
#include <apr_fnmatch.h>
+
+#include "svn_private_config.h"
#include "svn_client.h"
#include "svn_dirent_uri.h"
#include "svn_diff.h"
@@ -42,7 +44,6 @@
#include "svn_wc.h"
#include "client.h"
-#include "svn_private_config.h"
#include "private/svn_eol_private.h"
#include "private/svn_wc_private.h"
#include "private/svn_dep_compat.h"
@@ -2676,8 +2677,8 @@ install_patched_prop_targets(patch_targe
{
if (! dry_run)
{
- SVN_ERR(svn_io_file_create(target->local_abspath, "",
- scratch_pool));
+ SVN_ERR(svn_io_file_create_empty(target->local_abspath,
+ scratch_pool));
SVN_ERR(svn_wc_add_from_disk2(ctx->wc_ctx, target->local_abspath,
NULL /*props*/,
/* suppress notification */
@@ -2815,10 +2816,13 @@ check_ancestor_delete(const char *delete
{
struct can_delete_baton_t cb;
svn_error_t *err;
+ apr_array_header_t *ignores;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
const char *dir_abspath = svn_dirent_dirname(deleted_target, scratch_pool);
+ SVN_ERR(svn_wc_get_default_ignores(&ignores, ctx->config, scratch_pool));
+
while (svn_dirent_is_child(apply_root, dir_abspath, iterpool))
{
svn_pool_clear(iterpool);
@@ -2828,7 +2832,7 @@ check_ancestor_delete(const char *delete
cb.targets_info = targets_info;
err = svn_wc_walk_status(ctx->wc_ctx, dir_abspath, svn_depth_infinity,
- TRUE, FALSE, FALSE, NULL,
+ TRUE, FALSE, FALSE, ignores,
can_delete_callback, &cb,
ctx->cancel_func, ctx->cancel_baton,
iterpool);
Modified: subversion/branches/cache-server/subversion/libsvn_client/prop_commands.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/prop_commands.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/prop_commands.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/prop_commands.c Tue Oct 15 08:52:06 2013
@@ -30,6 +30,7 @@
#define APR_WANT_STRFUNC
#include <apr_want.h>
+#include "svn_private_config.h"
#include "svn_error.h"
#include "svn_client.h"
#include "client.h"
@@ -40,7 +41,6 @@
#include "svn_hash.h"
#include "svn_sorts.h"
-#include "svn_private_config.h"
#include "private/svn_wc_private.h"
#include "private/svn_ra_private.h"
#include "private/svn_client_private.h"
Modified: subversion/branches/cache-server/subversion/libsvn_client/ra.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/ra.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/ra.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/ra.c Tue Oct 15 08:52:06 2013
@@ -25,6 +25,7 @@
#include <apr_pools.h>
+#include "svn_private_config.h"
#include "svn_error.h"
#include "svn_hash.h"
#include "svn_pools.h"
@@ -39,7 +40,6 @@
#include "client.h"
#include "mergeinfo.h"
-#include "svn_private_config.h"
#include "private/svn_wc_private.h"
#include "private/svn_client_private.h"
@@ -70,6 +70,8 @@ typedef struct callback_baton_t
/* A client context. */
svn_client_ctx_t *ctx;
+ /* Last progress reported by progress callback. */
+ apr_off_t last_progress;
} callback_baton_t;
@@ -158,7 +160,7 @@ push_wc_prop(void *baton,
if (! cb->commit_items)
return svn_error_createf
(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
- _("Attempt to set wc property '%s' on '%s' in a non-commit operation"),
+ _("Attempt to set wcprop '%s' on '%s' in a non-commit operation"),
name, svn_dirent_local_style(relpath, pool));
for (i = 0; i < cb->commit_items->nelts; i++)
@@ -287,6 +289,28 @@ get_client_string(void *baton,
return SVN_NO_ERROR;
}
+/* Implements svn_ra_progress_notify_func_t. Accumulates progress information
+ * for different RA sessions and reports total progress to caller. */
+static void
+progress_func(apr_off_t progress,
+ apr_off_t total,
+ void *baton,
+ apr_pool_t *pool)
+{
+ callback_baton_t *b = baton;
+ svn_client_ctx_t *ctx = b->ctx;
+
+ ctx->progress += (progress - b->last_progress);
+ b->last_progress = progress;
+
+ if (ctx->progress_func)
+ {
+ /* All RA implementations currently provide -1 for total. So it doesn't
+ make sense to develop some complex logic to combine total across all
+ RA sessions. */
+ ctx->progress_func(ctx->progress, -1, ctx->progress_baton, pool);
+ }
+}
#define SVN_CLIENT__MAX_REDIRECT_ATTEMPTS 3 /* ### TODO: Make configurable. */
@@ -320,12 +344,16 @@ svn_client__open_ra_session_internal(svn
cbtable->invalidate_wc_props = (write_dav_props && read_dav_props)
? invalidate_wc_props : NULL;
cbtable->auth_baton = ctx->auth_baton; /* new-style */
- cbtable->progress_func = ctx->progress_func;
- cbtable->progress_baton = ctx->progress_baton;
+ cbtable->progress_func = progress_func;
+ cbtable->progress_baton = cb;
cbtable->cancel_func = ctx->cancel_func ? cancel_callback : NULL;
cbtable->get_client_string = get_client_string;
if (base_dir_abspath)
cbtable->get_wc_contents = get_wc_contents;
+ cbtable->check_tunnel_func = ctx->check_tunnel_func;
+ cbtable->open_tunnel_func = ctx->open_tunnel_func;
+ cbtable->close_tunnel_func = ctx->close_tunnel_func;
+ cbtable->tunnel_baton = ctx->tunnel_baton;
cb->commit_items = commit_items;
cb->ctx = ctx;
@@ -447,39 +475,14 @@ svn_client_open_ra_session2(svn_ra_sessi
scratch_pool));
}
-
-
-
-/* Given PATH_OR_URL, which contains either a working copy path or an
- absolute URL, a peg revision PEG_REVISION, and a desired revision
- REVISION, find the path at which that object exists in REVISION,
- following copy history if necessary. If REVISION is younger than
- PEG_REVISION, then check that PATH_OR_URL is the same node in both
- PEG_REVISION and REVISION, and return @c
- SVN_ERR_CLIENT_UNRELATED_RESOURCES if it is not the same node.
-
- If PEG_REVISION->kind is 'unspecified', the peg revision is 'head'
- for a URL or 'working' for a WC path. If REVISION->kind is
- 'unspecified', the operative revision is the peg revision.
-
- Store the actual location of the object in *RESOLVED_LOC_P.
-
- RA_SESSION should be an open RA session pointing at the URL of
- PATH_OR_URL, or NULL, in which case this function will open its own
- temporary session.
-
- Use authentication baton cached in CTX to authenticate against the
- repository.
-
- Use POOL for all allocations. */
-static svn_error_t *
-resolve_rev_and_url(svn_client__pathrev_t **resolved_loc_p,
- svn_ra_session_t *ra_session,
- const char *path_or_url,
- const svn_opt_revision_t *peg_revision,
- const svn_opt_revision_t *revision,
- svn_client_ctx_t *ctx,
- apr_pool_t *pool)
+svn_error_t *
+svn_client__resolve_rev_and_url(svn_client__pathrev_t **resolved_loc_p,
+ svn_ra_session_t *ra_session,
+ const char *path_or_url,
+ const svn_opt_revision_t *peg_revision,
+ const svn_opt_revision_t *revision,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
{
svn_opt_revision_t peg_rev = *peg_revision;
svn_opt_revision_t start_rev = *revision;
@@ -545,9 +548,9 @@ svn_client__ra_session_from_path2(svn_ra
if (corrected_url && svn_path_is_url(path_or_url))
path_or_url = corrected_url;
- SVN_ERR(resolve_rev_and_url(&resolved_loc, ra_session,
- path_or_url, peg_revision, revision,
- ctx, pool));
+ SVN_ERR(svn_client__resolve_rev_and_url(&resolved_loc, ra_session,
+ path_or_url, peg_revision, revision,
+ ctx, pool));
/* Make the session point to the real URL. */
SVN_ERR(svn_ra_reparent(ra_session, resolved_loc->url, pool));
@@ -652,6 +655,9 @@ svn_client__repos_location_segments(apr_
* END_REVNUM must be valid revision numbers except that END_REVNUM may
* be SVN_INVALID_REVNUM if END_URL is NULL.
*
+ * YOUNGEST_REV is the already retrieved youngest revision of the ra session,
+ * but can be SVN_INVALID_REVNUM if the value is not already retrieved.
+ *
* RA_SESSION is an open RA session parented at URL.
*/
static svn_error_t *
@@ -662,6 +668,7 @@ repos_locations(const char **start_url,
svn_revnum_t peg_revnum,
svn_revnum_t start_revnum,
svn_revnum_t end_revnum,
+ svn_revnum_t youngest_rev,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -669,9 +676,9 @@ repos_locations(const char **start_url,
apr_array_header_t *revs;
apr_hash_t *rev_locs;
- SVN_ERR_ASSERT(peg_revnum != SVN_INVALID_REVNUM);
- SVN_ERR_ASSERT(start_revnum != SVN_INVALID_REVNUM);
- SVN_ERR_ASSERT(end_revnum != SVN_INVALID_REVNUM || end_url == NULL);
+ SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(peg_revnum));
+ SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(start_revnum));
+ SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(end_revnum) || end_url == NULL);
/* Avoid a network request in the common easy case. */
if (start_revnum == peg_revnum
@@ -686,6 +693,27 @@ repos_locations(const char **start_url,
SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_url, scratch_pool));
+ /* Handle another common case: The repository root can't move */
+ if (! strcmp(repos_url, url))
+ {
+ if (! SVN_IS_VALID_REVNUM(youngest_rev))
+ SVN_ERR(svn_ra_get_latest_revnum(ra_session, &youngest_rev,
+ scratch_pool));
+
+ if (start_revnum > youngest_rev
+ || (SVN_IS_VALID_REVNUM(end_revnum) && (end_revnum > youngest_rev)))
+ return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
+ _("No such revision %ld"),
+ (start_revnum > youngest_rev)
+ ? start_revnum : end_revnum);
+
+ if (start_url)
+ *start_url = apr_pstrdup(result_pool, repos_url);
+ if (end_url)
+ *end_url = apr_pstrdup(result_pool, repos_url);
+ return SVN_NO_ERROR;
+ }
+
revs = apr_array_make(scratch_pool, 2, sizeof(svn_revnum_t));
APR_ARRAY_PUSH(revs, svn_revnum_t) = start_revnum;
if (end_revnum != start_revnum && end_revnum != SVN_INVALID_REVNUM)
@@ -741,7 +769,7 @@ svn_client__repos_location(svn_client__p
peg_loc->url, scratch_pool));
err = repos_locations(&op_url, NULL, ra_session,
peg_loc->url, peg_loc->rev,
- op_revnum, SVN_INVALID_REVNUM,
+ op_revnum, SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
result_pool, scratch_pool);
SVN_ERR(svn_error_compose_create(
err, svn_ra_reparent(ra_session, old_session_url, scratch_pool)));
@@ -881,29 +909,26 @@ svn_client__repos_locations(const char *
SVN_ERR(repos_locations(start_url, end_url,
ra_session, url, peg_revnum,
- start_revnum, end_revnum,
+ start_revnum, end_revnum, youngest_rev,
pool, subpool));
svn_pool_destroy(subpool);
return SVN_NO_ERROR;
}
-
svn_error_t *
-svn_client__get_youngest_common_ancestor(svn_client__pathrev_t **ancestor_p,
- const svn_client__pathrev_t *loc1,
- const svn_client__pathrev_t *loc2,
- svn_ra_session_t *session,
- svn_client_ctx_t *ctx,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+svn_client__calc_youngest_common_ancestor(svn_client__pathrev_t **ancestor_p,
+ const svn_client__pathrev_t *loc1,
+ apr_hash_t *history1,
+ svn_boolean_t has_rev_zero_history1,
+ const svn_client__pathrev_t *loc2,
+ apr_hash_t *history2,
+ svn_boolean_t has_rev_zero_history2,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
- apr_pool_t *sesspool = NULL;
- apr_hash_t *history1, *history2;
apr_hash_index_t *hi;
svn_revnum_t yc_revision = SVN_INVALID_REVNUM;
const char *yc_relpath = NULL;
- svn_boolean_t has_rev_zero_history1;
- svn_boolean_t has_rev_zero_history2;
if (strcmp(loc1->repos_root_url, loc2->repos_root_url) != 0)
{
@@ -911,32 +936,6 @@ svn_client__get_youngest_common_ancestor
return SVN_NO_ERROR;
}
- /* Open an RA session for the two locations. */
- if (session == NULL)
- {
- sesspool = svn_pool_create(scratch_pool);
- SVN_ERR(svn_client_open_ra_session2(&session, loc1->url, NULL, ctx,
- sesspool, sesspool));
- }
-
- /* We're going to cheat and use history-as-mergeinfo because it
- saves us a bunch of annoying custom data comparisons and such. */
- SVN_ERR(svn_client__get_history_as_mergeinfo(&history1,
- &has_rev_zero_history1,
- loc1,
- SVN_INVALID_REVNUM,
- SVN_INVALID_REVNUM,
- session, ctx, scratch_pool));
- SVN_ERR(svn_client__get_history_as_mergeinfo(&history2,
- &has_rev_zero_history2,
- loc2,
- SVN_INVALID_REVNUM,
- SVN_INVALID_REVNUM,
- session, ctx, scratch_pool));
- /* Close the ra session if we opened one. */
- if (sesspool)
- svn_pool_destroy(sesspool);
-
/* Loop through the first location's history, check for overlapping
paths and ranges in the second location's history, and
remembering the youngest matching location. */
@@ -990,47 +989,62 @@ svn_client__get_youngest_common_ancestor
}
svn_error_t *
-svn_client__youngest_common_ancestor(const char **ancestor_url,
- svn_revnum_t *ancestor_rev,
- const char *path_or_url1,
- const svn_opt_revision_t *revision1,
- const char *path_or_url2,
- const svn_opt_revision_t *revision2,
- svn_client_ctx_t *ctx,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+svn_client__get_youngest_common_ancestor(svn_client__pathrev_t **ancestor_p,
+ const svn_client__pathrev_t *loc1,
+ const svn_client__pathrev_t *loc2,
+ svn_ra_session_t *session,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
- apr_pool_t *sesspool = svn_pool_create(scratch_pool);
- svn_ra_session_t *session;
- svn_client__pathrev_t *loc1, *loc2, *ancestor;
-
- /* Resolve the two locations */
- SVN_ERR(svn_client__ra_session_from_path2(&session, &loc1,
- path_or_url1, NULL,
- revision1, revision1,
- ctx, sesspool));
- SVN_ERR(resolve_rev_and_url(&loc2, session,
- path_or_url2, revision2, revision2,
- ctx, scratch_pool));
-
- SVN_ERR(svn_client__get_youngest_common_ancestor(
- &ancestor, loc1, loc2, session, ctx, result_pool, scratch_pool));
+ apr_pool_t *sesspool = NULL;
+ apr_hash_t *history1, *history2;
+ svn_boolean_t has_rev_zero_history1;
+ svn_boolean_t has_rev_zero_history2;
- if (ancestor)
+ if (strcmp(loc1->repos_root_url, loc2->repos_root_url) != 0)
{
- *ancestor_url = ancestor->url;
- *ancestor_rev = ancestor->rev;
+ *ancestor_p = NULL;
+ return SVN_NO_ERROR;
}
- else
+
+ /* Open an RA session for the two locations. */
+ if (session == NULL)
{
- *ancestor_url = NULL;
- *ancestor_rev = SVN_INVALID_REVNUM;
+ sesspool = svn_pool_create(scratch_pool);
+ SVN_ERR(svn_client_open_ra_session2(&session, loc1->url, NULL, ctx,
+ sesspool, sesspool));
}
- svn_pool_destroy(sesspool);
+
+ /* We're going to cheat and use history-as-mergeinfo because it
+ saves us a bunch of annoying custom data comparisons and such. */
+ SVN_ERR(svn_client__get_history_as_mergeinfo(&history1,
+ &has_rev_zero_history1,
+ loc1,
+ SVN_INVALID_REVNUM,
+ SVN_INVALID_REVNUM,
+ session, ctx, scratch_pool));
+ SVN_ERR(svn_client__get_history_as_mergeinfo(&history2,
+ &has_rev_zero_history2,
+ loc2,
+ SVN_INVALID_REVNUM,
+ SVN_INVALID_REVNUM,
+ session, ctx, scratch_pool));
+ /* Close the ra session if we opened one. */
+ if (sesspool)
+ svn_pool_destroy(sesspool);
+
+ SVN_ERR(svn_client__calc_youngest_common_ancestor(ancestor_p,
+ loc1, history1,
+ has_rev_zero_history1,
+ loc2, history2,
+ has_rev_zero_history2,
+ result_pool,
+ scratch_pool));
+
return SVN_NO_ERROR;
}
-
struct ra_ev2_baton {
/* The working copy context, from the client context. */
svn_wc_context_t *wc_ctx;
Modified: subversion/branches/cache-server/subversion/libsvn_client/repos_diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/repos_diff.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/repos_diff.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/repos_diff.c Tue Oct 15 08:52:06 2013
@@ -36,6 +36,7 @@
#include <apr_md5.h>
#include <assert.h>
+#include "svn_private_config.h"
#include "svn_checksum.h"
#include "svn_hash.h"
#include "svn_wc.h"
@@ -44,7 +45,6 @@
#include "svn_path.h"
#include "svn_io.h"
#include "svn_props.h"
-#include "svn_private_config.h"
#include "client.h"
@@ -328,7 +328,7 @@ get_file_from_ra(struct file_baton *fb,
fb->pool, scratch_pool));
fstream = svn_stream_checksummed2(fstream, NULL, &fb->start_md5_checksum,
- svn_checksum_md5, TRUE, scratch_pool);
+ svn_checksum_md5, TRUE, fb->pool);
/* Retrieve the file and its properties */
SVN_ERR(svn_ra_get_file(fb->edit_baton->ra_session,
@@ -933,12 +933,12 @@ apply_textdelta(void *file_baton,
}
/* Open the file to be used as the base for second revision */
- src_stream = svn_stream_lazyopen_create(lazy_open_source, fb, FALSE,
+ src_stream = svn_stream_lazyopen_create(lazy_open_source, fb, TRUE,
scratch_pool);
/* Open the file that will become the second revision after applying the
text delta, it starts empty */
- result_stream = svn_stream_lazyopen_create(lazy_open_result, fb, FALSE,
+ result_stream = svn_stream_lazyopen_create(lazy_open_result, fb, TRUE,
scratch_pool);
svn_txdelta_apply(src_stream,
Modified: subversion/branches/cache-server/subversion/libsvn_client/resolved.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/resolved.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/resolved.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/resolved.c Tue Oct 15 08:52:06 2013
@@ -29,6 +29,7 @@
#include <stdlib.h>
+#include "svn_private_config.h"
#include "svn_types.h"
#include "svn_wc.h"
#include "svn_client.h"
@@ -40,8 +41,6 @@
#include "svn_sorts.h"
#include "client.h"
#include "private/svn_wc_private.h"
-
-#include "svn_private_config.h"
/*** Code. ***/
Modified: subversion/branches/cache-server/subversion/libsvn_client/revert.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/revert.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/revert.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/revert.c Tue Oct 15 08:52:06 2013
@@ -27,6 +27,7 @@
/*** Includes. ***/
+#include "svn_private_config.h"
#include "svn_path.h"
#include "svn_wc.h"
#include "svn_client.h"
@@ -39,8 +40,6 @@
#include "client.h"
#include "private/svn_wc_private.h"
-#include "svn_private_config.h"
-
/*** Code. ***/
Modified: subversion/branches/cache-server/subversion/libsvn_client/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/status.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/status.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/status.c Tue Oct 15 08:52:06 2013
@@ -29,6 +29,7 @@
#include <apr_strings.h>
#include <apr_pools.h>
+#include "svn_private_config.h"
#include "svn_pools.h"
#include "client.h"
@@ -39,7 +40,6 @@
#include "svn_error.h"
#include "svn_hash.h"
-#include "svn_private_config.h"
#include "private/svn_wc_private.h"
#include "private/svn_client_private.h"
Modified: subversion/branches/cache-server/subversion/libsvn_client/switch.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/switch.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/switch.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/switch.c Tue Oct 15 08:52:06 2013
@@ -27,6 +27,7 @@
/*** Includes. ***/
+#include "svn_private_config.h"
#include "svn_client.h"
#include "svn_error.h"
#include "svn_hash.h"
@@ -37,7 +38,6 @@
#include "svn_pools.h"
#include "client.h"
-#include "svn_private_config.h"
#include "private/svn_wc_private.h"
@@ -231,8 +231,6 @@ switch_internal(svn_revnum_t *result_rev
yca = NULL; /* Not versioned */
else
{
- /* ### It would be nice if this function could reuse the existing
- ra session instead of opening two for its own use. */
SVN_ERR(svn_client__get_youngest_common_ancestor(
&yca, switch_loc, target_base_loc, ra_session, ctx,
pool, pool));
@@ -241,7 +239,7 @@ switch_internal(svn_revnum_t *result_rev
return svn_error_createf(SVN_ERR_CLIENT_UNRELATED_RESOURCES, NULL,
_("'%s' shares no common ancestry with '%s'"),
switch_url,
- svn_dirent_dirname(local_abspath, pool));
+ svn_dirent_local_style(local_abspath, pool));
}
wcroot_iprops = apr_hash_make(pool);
@@ -340,8 +338,8 @@ switch_internal(svn_revnum_t *result_rev
*timestamp_sleep = TRUE;
/* Drive the reporter structure, describing the revisions within
- PATH. When we call reporter->finish_report, the update_editor
- will be driven by svn_repos_dir_delta2. */
+ LOCAL_ABSPATH. When this calls reporter->finish_report, the
+ reporter will drive the switch_editor. */
SVN_ERR(svn_wc_crawl_revisions5(ctx->wc_ctx, local_abspath, reporter,
report_baton, TRUE,
depth, (! depth_is_sticky),
Modified: subversion/branches/cache-server/subversion/libsvn_client/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/update.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/update.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/update.c Tue Oct 15 08:52:06 2013
@@ -27,6 +27,7 @@
/*** Includes. ***/
+#include "svn_private_config.h"
#include "svn_hash.h"
#include "svn_wc.h"
#include "svn_client.h"
@@ -39,7 +40,6 @@
#include "svn_io.h"
#include "client.h"
-#include "svn_private_config.h"
#include "private/svn_wc_private.h"
/* Implements svn_wc_dirents_func_t for update and switch handling. Assumes
@@ -454,8 +454,8 @@ update_internal(svn_revnum_t *result_rev
*timestamp_sleep = TRUE;
/* Drive the reporter structure, describing the revisions within
- PATH. When we call reporter->finish_report, the
- update_editor will be driven by svn_repos_dir_delta2. */
+ LOCAL_ABSPATH. When this calls reporter->finish_report, the
+ reporter will drive the update_editor. */
SVN_ERR(svn_wc_crawl_revisions5(ctx->wc_ctx, local_abspath, reporter,
report_baton, TRUE,
depth, (! depth_is_sticky),
@@ -701,7 +701,23 @@ svn_client_update4(apr_array_header_t **
cleanup:
if (sleep)
- svn_io_sleep_for_timestamps((paths->nelts == 1) ? path : NULL, pool);
+ {
+ const char *wcroot_abspath;
+
+ if (paths->nelts == 1)
+ {
+ const char *abspath;
+
+ /* PATH iteslf may have been removed by the update. */
+ SVN_ERR(svn_dirent_get_absolute(&abspath, path, pool));
+ SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, ctx->wc_ctx, abspath,
+ pool, pool));
+ }
+ else
+ wcroot_abspath = NULL;
+
+ svn_io_sleep_for_timestamps(wcroot_abspath, pool);
+ }
return svn_error_trace(err);
}
Modified: subversion/branches/cache-server/subversion/libsvn_client/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_client/util.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_client/util.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_client/util.c Tue Oct 15 08:52:06 2013
@@ -24,6 +24,7 @@
#include <apr_pools.h>
#include <apr_strings.h>
+#include "svn_private_config.h"
#include "svn_hash.h"
#include "svn_pools.h"
#include "svn_error.h"
@@ -40,8 +41,6 @@
#include "client.h"
-#include "svn_private_config.h"
-
svn_client__pathrev_t *
svn_client__pathrev_create(const char *repos_root_url,
const char *repos_uuid,
Modified: subversion/branches/cache-server/subversion/libsvn_delta/compat.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_delta/compat.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_delta/compat.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_delta/compat.c Tue Oct 15 08:52:06 2013
@@ -23,6 +23,7 @@
#include <stddef.h>
+#include "svn_private_config.h"
#include "svn_types.h"
#include "svn_error.h"
#include "svn_delta.h"
@@ -33,8 +34,6 @@
#include "svn_props.h"
#include "svn_pools.h"
-#include "svn_private_config.h"
-
#include "private/svn_delta_private.h"
@@ -218,6 +217,7 @@ locate_change(struct ev2_edit_baton *eb,
change = apr_pcalloc(eb->edit_pool, sizeof(*change));
change->changing = SVN_INVALID_REVNUM;
change->deleting = SVN_INVALID_REVNUM;
+ change->kind = svn_node_unknown;
svn_hash_sets(eb->changes, relpath, change);
@@ -439,8 +439,8 @@ process_actions(struct ev2_edit_baton *e
change->changing, NULL, props));
else
SVN_ERR(svn_editor_alter_file(eb->editor, repos_relpath,
- change->changing, props,
- checksum, contents));
+ change->changing,
+ checksum, contents, props));
}
return SVN_NO_ERROR;
@@ -1182,9 +1182,9 @@ static svn_error_t *
alter_file_cb(void *baton,
const char *relpath,
svn_revnum_t revision,
- apr_hash_t *props,
const svn_checksum_t *checksum,
svn_stream_t *contents,
+ apr_hash_t *props,
apr_pool_t *scratch_pool)
{
struct editor_baton *eb = baton;
@@ -1234,8 +1234,8 @@ static svn_error_t *
alter_symlink_cb(void *baton,
const char *relpath,
svn_revnum_t revision,
- apr_hash_t *props,
const char *target,
+ apr_hash_t *props,
apr_pool_t *scratch_pool)
{
/* ### should we verify the kind is truly a symlink? */
@@ -1330,17 +1330,6 @@ move_cb(void *baton,
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)
-{
- SVN__NOT_IMPLEMENTED();
-}
-
-
static int
count_components(const char *relpath)
{
@@ -1633,11 +1622,14 @@ apply_change(void **dir_baton,
change->copyfrom_path,
scratch_pool);
else
- copyfrom_url = change->copyfrom_path;
+ {
+ 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);
+ /* 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;
}
@@ -1885,7 +1877,6 @@ svn_delta__editor_from_delta(svn_editor_
delete_cb,
copy_cb,
move_cb,
- rotate_cb,
complete_cb,
abort_cb
};
Modified: subversion/branches/cache-server/subversion/libsvn_delta/compose_delta.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_delta/compose_delta.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_delta/compose_delta.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_delta/compose_delta.c Tue Oct 15 08:52:06 2013
@@ -648,15 +648,17 @@ copy_source_ops(apr_size_t offset, apr_s
{
const svn_txdelta_op_t *const op = &window->ops[op_ndx];
const apr_size_t *const off = &ndx->offs[op_ndx];
- apr_size_t fix_offset;
- apr_size_t fix_limit;
+ const apr_size_t fix_offset = (offset > off[0] ? offset - off[0] : 0);
+ const apr_size_t fix_limit = (off[1] > limit ? off[1] - limit : 0);
+ /* Ideally, we'd do this check before assigning fix_offset and
+ fix_limit; but then we couldn't make them const whilst still
+ adhering to C90 rules. Instead, we're going to assume that a
+ smart optimizing compiler will reorder this check before the
+ local variable initialization. */
if (off[0] >= limit)
break;
- fix_offset = (offset > off[0] ? offset - off[0] : 0);
- fix_limit = (off[1] > limit ? off[1] - limit : 0);
-
/* It would be extremely weird if the fixed-up op had zero length. */
assert(fix_offset + fix_limit < op->length);
@@ -701,23 +703,22 @@ copy_source_ops(apr_size_t offset, apr_s
apr_size_t tgt_off = target_offset;
assert(ptn_length > ptn_overlap);
- /* ### FIXME: ptn_overlap is unsigned, so the if() condition
- below is always true! Either it should be '> 0', or the
- code block should be unconditional. See also r842362. */
- if (ptn_overlap >= 0)
- {
- /* Issue second subrange in the pattern. */
- const apr_size_t length =
- MIN(op->length - fix_off - fix_limit,
- ptn_length - ptn_overlap);
- copy_source_ops(op->offset + ptn_overlap,
- op->offset + ptn_overlap + length,
- tgt_off,
- op_ndx,
- build_baton, window, ndx, pool);
- fix_off += length;
- tgt_off += length;
- }
+ /* Unconditionally issue the second subrange of the
+ pattern. This is always correct, since the outer
+ condition already verifies that there is an overlap
+ in the target copy. */
+ {
+ const apr_size_t length =
+ MIN(op->length - fix_off - fix_limit,
+ ptn_length - ptn_overlap);
+ copy_source_ops(op->offset + ptn_overlap,
+ op->offset + ptn_overlap + length,
+ tgt_off,
+ op_ndx,
+ build_baton, window, ndx, pool);
+ fix_off += length;
+ tgt_off += length;
+ }
assert(fix_off + fix_limit <= op->length);
if (ptn_overlap > 0
Modified: subversion/branches/cache-server/subversion/libsvn_delta/editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_delta/editor.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_delta/editor.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_delta/editor.c Tue Oct 15 08:52:06 2013
@@ -391,16 +391,6 @@ 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)
@@ -437,7 +427,6 @@ 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);
@@ -683,9 +672,9 @@ svn_error_t *
svn_editor_alter_file(svn_editor_t *editor,
const char *relpath,
svn_revnum_t revision,
- apr_hash_t *props,
const svn_checksum_t *checksum,
- svn_stream_t *contents)
+ svn_stream_t *contents,
+ apr_hash_t *props)
{
svn_error_t *err = SVN_NO_ERROR;
@@ -705,8 +694,8 @@ svn_editor_alter_file(svn_editor_t *edit
{
START_CALLBACK(editor);
err = editor->funcs.cb_alter_file(editor->baton,
- relpath, revision, props,
- checksum, contents,
+ relpath, revision,
+ checksum, contents, props,
editor->scratch_pool);
END_CALLBACK(editor);
}
@@ -723,8 +712,8 @@ svn_error_t *
svn_editor_alter_symlink(svn_editor_t *editor,
const char *relpath,
svn_revnum_t revision,
- apr_hash_t *props,
- const char *target)
+ const char *target,
+ apr_hash_t *props)
{
svn_error_t *err = SVN_NO_ERROR;
@@ -740,8 +729,8 @@ svn_editor_alter_symlink(svn_editor_t *e
{
START_CALLBACK(editor);
err = editor->funcs.cb_alter_symlink(editor->baton,
- relpath, revision, props,
- target,
+ relpath, revision,
+ target, props,
editor->scratch_pool);
END_CALLBACK(editor);
}
@@ -862,56 +851,6 @@ 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;
-
- SHOULD_NOT_BE_FINISHED(editor);
-#ifdef ENABLE_ORDERING_CHECK
- {
- int i;
- for (i = 0; i < relpaths->nelts; i++)
- {
- const char *relpath = APR_ARRAY_IDX(relpaths, i, const char *);
-
- SVN_ERR_ASSERT(svn_relpath_is_canonical(relpath));
- SHOULD_NOT_BE_COMPLETED(editor, relpath);
- VERIFY_PARENT_MAY_EXIST(editor, relpath);
- CHILD_DELETIONS_ALLOWED(editor, relpath);
- }
- }
-#endif
-
- SVN_ERR(check_cancel(editor));
-
- if (editor->funcs.cb_rotate)
- {
- START_CALLBACK(editor);
- err = editor->funcs.cb_rotate(editor->baton, relpaths, revisions,
- editor->scratch_pool);
- END_CALLBACK(editor);
- }
-
-#ifdef ENABLE_ORDERING_CHECK
- {
- int i;
- for (i = 0; i < relpaths->nelts; i++)
- {
- const char *relpath = APR_ARRAY_IDX(relpaths, i, const char *);
- MARK_ALLOW_ALTER(editor, relpath);
- MARK_PARENT_STABLE(editor, relpath);
- }
- }
-#endif
-
- svn_pool_clear(editor->scratch_pool);
- return svn_error_trace(err);
-}
-
-
-svn_error_t *
svn_editor_complete(svn_editor_t *editor)
{
svn_error_t *err = SVN_NO_ERROR;
Modified: subversion/branches/cache-server/subversion/libsvn_delta/svndiff.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_delta/svndiff.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_delta/svndiff.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_delta/svndiff.c Tue Oct 15 08:52:06 2013
@@ -29,21 +29,12 @@
#include "delta.h"
#include "svn_pools.h"
#include "svn_private_config.h"
-#include <zlib.h>
#include "private/svn_error_private.h"
#include "private/svn_delta_private.h"
-
-/* The zlib compressBound function was not exported until 1.2.0. */
-#if ZLIB_VERNUM >= 0x1200
-#define svnCompressBound(LEN) compressBound(LEN)
-#else
-#define svnCompressBound(LEN) ((LEN) + ((LEN) >> 12) + ((LEN) >> 14) + 11)
-#endif
-
-/* For svndiff1, address/instruction/new data under this size will not
- be compressed using zlib as a secondary compressor. */
-#define MIN_COMPRESS_SIZE 512
+#include "private/svn_subr_private.h"
+#include "private/svn_string_private.h"
+#include "private/svn_dep_compat.h"
/* ----- Text delta to svndiff ----- */
@@ -58,139 +49,31 @@ struct encoder_baton {
apr_pool_t *pool;
};
-/* This is at least as big as the largest size of an integer that
- encode_int can generate; it is sufficient for creating buffers for
- it to write into. This assumes that integers are at most 64 bits,
- and so 10 bytes (with 7 bits of information each) are sufficient to
- represent them. */
-#define MAX_ENCODED_INT_LEN 10
/* This is at least as big as the largest size for a single instruction. */
-#define MAX_INSTRUCTION_LEN (2*MAX_ENCODED_INT_LEN+1)
+#define MAX_INSTRUCTION_LEN (2*SVN__MAX_ENCODED_UINT_LEN+1)
/* This is at least as big as the largest possible instructions
section: in theory, the instructions could be SVN_DELTA_WINDOW_SIZE
1-byte copy-from-source instructions (though this is very unlikely). */
#define MAX_INSTRUCTION_SECTION_LEN (SVN_DELTA_WINDOW_SIZE*MAX_INSTRUCTION_LEN)
-/* Encode VAL into the buffer P using the variable-length svndiff
- integer format. Return the incremented value of P after the
- encoded bytes have been written. P must point to a buffer of size
- at least MAX_ENCODED_INT_LEN.
-
- This encoding uses the high bit of each byte as a continuation bit
- and the other seven bits as data bits. High-order data bits are
- encoded first, followed by lower-order bits, so the value can be
- reconstructed by concatenating the data bits from left to right and
- interpreting the result as a binary number. Examples (brackets
- denote byte boundaries, spaces are for clarity only):
-
- 1 encodes as [0 0000001]
- 33 encodes as [0 0100001]
- 129 encodes as [1 0000001] [0 0000001]
- 2000 encodes as [1 0001111] [0 1010000]
-*/
-static unsigned char *
-encode_int(unsigned char *p, svn_filesize_t val)
-{
- int n;
- svn_filesize_t v;
- unsigned char cont;
-
- SVN_ERR_ASSERT_NO_RETURN(val >= 0);
-
- /* Figure out how many bytes we'll need. */
- v = val >> 7;
- n = 1;
- while (v > 0)
- {
- v = v >> 7;
- n++;
- }
-
- SVN_ERR_ASSERT_NO_RETURN(n <= MAX_ENCODED_INT_LEN);
-
- /* Encode the remaining bytes; n is always the number of bytes
- coming after the one we're encoding. */
- while (--n >= 0)
- {
- cont = ((n > 0) ? 0x1 : 0x0) << 7;
- *p++ = (unsigned char)(((val >> (n * 7)) & 0x7f) | cont);
- }
-
- return p;
-}
-
/* Append an encoded integer to a string. */
static void
append_encoded_int(svn_stringbuf_t *header, svn_filesize_t val)
{
- unsigned char buf[MAX_ENCODED_INT_LEN], *p;
+ unsigned char buf[SVN__MAX_ENCODED_UINT_LEN], *p;
- p = encode_int(buf, val);
+ SVN_ERR_ASSERT_NO_RETURN(val >= 0);
+ p = svn__encode_uint(buf, (apr_uint64_t)val);
svn_stringbuf_appendbytes(header, (const char *)buf, p - buf);
}
-/* If IN is a string that is >= MIN_COMPRESS_SIZE and the COMPRESSION_LEVEL
- is not SVN_DELTA_COMPRESSION_LEVEL_NONE, zlib compress it and places the
- result in OUT, with an integer prepended specifying the original size.
- If IN is < MIN_COMPRESS_SIZE, or if the compressed version of IN was no
- smaller than the original IN, OUT will be a copy of IN with the size
- prepended as an integer. */
-static svn_error_t *
-zlib_encode(const char *data,
- apr_size_t len,
- svn_stringbuf_t *out,
- int compression_level)
-{
- unsigned long endlen;
- apr_size_t intlen;
-
- svn_stringbuf_setempty(out);
- append_encoded_int(out, len);
- intlen = out->len;
-
- /* Compression initialization overhead is considered to large for
- short buffers. Also, if we don't actually want to compress data,
- ZLIB will produce an output no shorter than the input. Hence,
- the DATA would directly appended to OUT, so we can do that directly
- without calling ZLIB before. */
- if ( (len < MIN_COMPRESS_SIZE)
- || (compression_level == SVN_DELTA_COMPRESSION_LEVEL_NONE))
- {
- svn_stringbuf_appendbytes(out, data, len);
- }
- else
- {
- int zerr;
-
- svn_stringbuf_ensure(out, svnCompressBound(len) + intlen);
- endlen = out->blocksize;
-
- zerr = compress2((unsigned char *)out->data + intlen, &endlen,
- (const unsigned char *)data, len,
- compression_level);
- if (zerr != Z_OK)
- return svn_error_trace(svn_error__wrap_zlib(
- zerr, "compress2",
- _("Compression of svndiff data failed")));
-
- /* Compression didn't help :(, just append the original text */
- if (endlen >= len)
- {
- svn_stringbuf_appendbytes(out, data, len);
- return SVN_NO_ERROR;
- }
- out->len = endlen + intlen;
- out->data[out->len] = 0;
- }
- return SVN_NO_ERROR;
-}
-
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 headers[4 + 5 * SVN__MAX_ENCODED_UINT_LEN
+ + MAX_INSTRUCTION_LEN];
unsigned char ibuf[MAX_INSTRUCTION_LEN];
unsigned char *header_current;
apr_size_t header_len;
@@ -226,16 +109,17 @@ send_simple_insertion_window(svn_txdelta
else
{
ibuf[0] = (0x2 << 6);
- ip_len = encode_int(ibuf + 1, window->tview_len) - ibuf;
+ ip_len = svn__encode_uint(ibuf + 1, window->tview_len) - ibuf;
}
/* encode the window header. Please note that the source window may
* have content despite not being used for deltification. */
- header_current = encode_int(header_current, window->sview_offset);
- header_current = encode_int(header_current, window->sview_len);
- header_current = encode_int(header_current, window->tview_len);
+ header_current = svn__encode_uint(header_current,
+ (apr_uint64_t)window->sview_offset);
+ header_current = svn__encode_uint(header_current, window->sview_len);
+ header_current = svn__encode_uint(header_current, window->tview_len);
header_current[0] = (unsigned char)ip_len; /* 1 instruction */
- header_current = encode_int(&header_current[1], len);
+ header_current = svn__encode_uint(&header_current[1], len);
/* append instructions (1 to a handful of bytes) */
for (i = 0; i < ip_len; ++i)
@@ -319,9 +203,9 @@ window_handler(svn_txdelta_window_t *win
if (op->length >> 6 == 0)
*ip++ |= (unsigned char)op->length;
else
- ip = encode_int(ip + 1, op->length);
+ ip = svn__encode_uint(ip + 1, op->length);
if (op->action_code != svn_txdelta_new)
- ip = encode_int(ip, op->offset);
+ ip = svn__encode_uint(ip, op->offset);
svn_stringbuf_appendbytes(instructions, (const char *)ibuf, ip - ibuf);
}
@@ -331,20 +215,20 @@ window_handler(svn_txdelta_window_t *win
append_encoded_int(header, window->tview_len);
if (eb->version == 1)
{
- SVN_ERR(zlib_encode(instructions->data, instructions->len,
- i1, eb->compression_level));
+ SVN_ERR(svn__compress(instructions, i1, eb->compression_level));
instructions = i1;
}
append_encoded_int(header, instructions->len);
if (eb->version == 1)
{
- svn_stringbuf_t *temp = svn_stringbuf_create_empty(pool);
- svn_string_t *tempstr = svn_string_create_empty(pool);
- SVN_ERR(zlib_encode(window->new_data->data, window->new_data->len,
- temp, eb->compression_level));
- tempstr->data = temp->data;
- tempstr->len = temp->len;
- newdata = tempstr;
+ svn_stringbuf_t *compressed = svn_stringbuf_create_empty(pool);
+ svn_stringbuf_t *original = svn_stringbuf_create_empty(pool);
+ original->data = (char *)window->new_data->data; /* won't be modified */
+ original->len = window->new_data->len;
+ original->blocksize = window->new_data->len + 1;
+
+ SVN_ERR(svn__compress(original, compressed, eb->compression_level));
+ newdata = svn_stringbuf__morph_into_string(compressed);
}
else
newdata = window->new_data;
@@ -453,128 +337,32 @@ struct decode_baton
};
-/* Decode an svndiff-encoded integer into *VAL and return a pointer to
- the byte after the integer. The bytes to be decoded live in the
- range [P..END-1]. If these bytes do not contain a whole encoded
- integer, return NULL; in this case *VAL is undefined.
-
- See the comment for encode_int() earlier in this file for more detail on
- the encoding format. */
+/* Wrapper aroung svn__deencode_uint taking a file size as *VAL. */
static const unsigned char *
decode_file_offset(svn_filesize_t *val,
const unsigned char *p,
const unsigned char *end)
{
- svn_filesize_t temp = 0;
-
- if (p + MAX_ENCODED_INT_LEN < end)
- end = p + MAX_ENCODED_INT_LEN;
- /* Decode bytes until we're done. */
- while (p < end)
- {
- /* Don't use svn_filesize_t here, because this might be 64 bits
- * on 32 bit targets. Optimizing compilers may or may not be
- * able to reduce that to the effective code below. */
- unsigned int c = *p++;
-
- temp = (temp << 7) | (c & 0x7f);
- if (c < 0x80)
- {
- *val = temp;
- return p;
- }
- }
+ apr_uint64_t temp = 0;
+ const unsigned char *result = svn__decode_uint(&temp, p, end);
+ *val = (svn_filesize_t)temp;
- return NULL;
+ return result;
}
-
/* Same as above, only decode into a size variable. */
static const unsigned char *
decode_size(apr_size_t *val,
const unsigned char *p,
const unsigned char *end)
{
- apr_size_t temp = 0;
-
- if (p + MAX_ENCODED_INT_LEN < end)
- end = p + MAX_ENCODED_INT_LEN;
- /* Decode bytes until we're done. */
- while (p < end)
- {
- apr_size_t c = *p++;
-
- temp = (temp << 7) | (c & 0x7f);
- if (c < 0x80)
- {
- *val = temp;
- return p;
- }
- }
-
- return NULL;
-}
-
-/* Decode the possibly-zlib compressed string of length INLEN that is in
- IN, into OUT. We expect an integer is prepended to IN that specifies
- the original size, and that if encoded size == original size, that the
- remaining data is not compressed.
- In that case, we will simply return pointer into IN as data pointer for
- OUT, COPYLESS_ALLOWED has been set. The, the caller is expected not to
- modify the contents of OUT.
- An error is returned if the decoded length exceeds the given LIMIT.
- */
-static svn_error_t *
-zlib_decode(const unsigned char *in, apr_size_t inLen, svn_stringbuf_t *out,
- apr_size_t limit)
-{
- apr_size_t len;
- const unsigned char *oldplace = in;
-
- /* First thing in the string is the original length. */
- in = decode_size(&len, in, in + inLen);
- if (in == NULL)
- return svn_error_create(SVN_ERR_SVNDIFF_INVALID_COMPRESSED_DATA, NULL,
- _("Decompression of svndiff data failed: no size"));
- if (len > limit)
- return svn_error_create(SVN_ERR_SVNDIFF_INVALID_COMPRESSED_DATA, NULL,
- _("Decompression of svndiff data failed: "
- "size too large"));
- /* We need to subtract the size of the encoded original length off the
- * still remaining input length. */
- inLen -= (in - oldplace);
- if (inLen == len)
- {
- svn_stringbuf_ensure(out, len);
- memcpy(out->data, in, len);
- out->data[len] = 0;
- out->len = len;
-
- return SVN_NO_ERROR;
- }
- else
- {
- unsigned long zlen = len;
- int zerr;
-
- svn_stringbuf_ensure(out, len);
- zerr = uncompress((unsigned char *)out->data, &zlen, in, inLen);
- if (zerr != Z_OK)
- return svn_error_trace(svn_error__wrap_zlib(
- zerr, "uncompress",
- _("Decompression of svndiff data failed")));
-
- /* Zlib should not produce something that has a different size than the
- original length we stored. */
- if (zlen != len)
- return svn_error_create(SVN_ERR_SVNDIFF_INVALID_COMPRESSED_DATA,
- NULL,
- _("Size of uncompressed data "
- "does not match stored original length"));
- out->data[zlen] = 0;
- out->len = zlen;
- }
- return SVN_NO_ERROR;
+ apr_uint64_t temp = 0;
+ const unsigned char *result = svn__decode_uint(&temp, p, end);
+ if (temp > APR_SIZE_MAX)
+ return NULL;
+
+ *val = (apr_size_t)temp;
+ return result;
}
/* Decode an instruction into OP, returning a pointer to the text
@@ -695,6 +483,21 @@ count_and_verify_instructions(int *ninst
return SVN_NO_ERROR;
}
+static svn_error_t *
+zlib_decode(const unsigned char *in, apr_size_t inLen, svn_stringbuf_t *out,
+ apr_size_t limit)
+{
+ /* construct a fake string buffer as parameter to svn__decompress.
+ This is fine as that function never writes to it. */
+ svn_stringbuf_t compressed;
+ compressed.pool = NULL;
+ compressed.data = (char *)in;
+ compressed.len = inLen;
+ compressed.blocksize = inLen + 1;
+
+ return svn__decompress(&compressed, out, limit);
+}
+
/* Given the five integer fields of a window header and a pointer to
the remainder of the window contents, fill in a delta window
structure *WINDOW. New allocations will be performed in POOL;
@@ -847,7 +650,7 @@ write_handler(void *baton,
if (tview_len > SVN_DELTA_WINDOW_SIZE ||
sview_len > SVN_DELTA_WINDOW_SIZE ||
/* for svndiff1, newlen includes the original length */
- newlen > SVN_DELTA_WINDOW_SIZE + MAX_ENCODED_INT_LEN ||
+ newlen > SVN_DELTA_WINDOW_SIZE + SVN__MAX_ENCODED_UINT_LEN ||
inslen > MAX_INSTRUCTION_SECTION_LEN)
return svn_error_create(SVN_ERR_SVNDIFF_CORRUPT_WINDOW, NULL,
_("Svndiff contains a too-large window"));
@@ -1029,7 +832,7 @@ read_window_header(svn_stream_t *stream,
if (*tview_len > SVN_DELTA_WINDOW_SIZE ||
*sview_len > SVN_DELTA_WINDOW_SIZE ||
/* for svndiff1, newlen includes the original length */
- *newlen > SVN_DELTA_WINDOW_SIZE + MAX_ENCODED_INT_LEN ||
+ *newlen > SVN_DELTA_WINDOW_SIZE + SVN__MAX_ENCODED_UINT_LEN ||
*inslen > MAX_INSTRUCTION_SECTION_LEN)
return svn_error_create(SVN_ERR_SVNDIFF_CORRUPT_WINDOW, NULL,
_("Svndiff contains a too-large window"));
@@ -1086,18 +889,3 @@ svn_txdelta_skip_svndiff_window(apr_file
}
-svn_error_t *
-svn__compress(svn_string_t *in,
- svn_stringbuf_t *out,
- int compression_level)
-{
- return zlib_encode(in->data, in->len, out, compression_level);
-}
-
-svn_error_t *
-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);
-}
Modified: subversion/branches/cache-server/subversion/libsvn_delta/text_delta.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_delta/text_delta.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_delta/text_delta.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_delta/text_delta.c Tue Oct 15 08:52:06 2013
@@ -669,7 +669,7 @@ patterning_copy(char *target, const char
#if SVN_UNALIGNED_ACCESS_IS_OK
- if (end + sizeof(apr_uint32_t) <= target)
+ if (source + sizeof(apr_uint32_t) <= target)
{
/* Source and target are at least 4 bytes apart, so we can copy in
* 4-byte chunks. */
Modified: subversion/branches/cache-server/subversion/libsvn_delta/xdelta.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_delta/xdelta.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_delta/xdelta.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_delta/xdelta.c Tue Oct 15 08:52:06 2013
@@ -27,8 +27,10 @@
#include <apr_general.h> /* for APR_INLINE */
#include <apr_hash.h>
+#include "svn_private_config.h"
#include "svn_hash.h"
#include "svn_delta.h"
+#include "private/svn_string_private.h"
#include "delta.h"
/* This is pseudo-adler32. It is adler32 without the prime modulus.
@@ -223,73 +225,6 @@ init_blocks_table(const char *data,
add_block(blocks, init_adler32(data + i), i);
}
-/* Return the lowest position at which A and B differ. If no difference
- * can be found in the first MAX_LEN characters, MAX_LEN will be returned.
- */
-static apr_size_t
-match_length(const char *a, const char *b, apr_size_t max_len)
-{
- apr_size_t pos = 0;
-
-#if SVN_UNALIGNED_ACCESS_IS_OK
-
- /* Chunky processing is so much faster ...
- *
- * We can't make this work on architectures that require aligned access
- * because A and B will probably have different alignment. So, skipping
- * the first few chars until alignment is reached is not an option.
- */
- for (; pos + sizeof(apr_size_t) <= max_len; pos += sizeof(apr_size_t))
- if (*(const apr_size_t*)(a + pos) != *(const apr_size_t*)(b + pos))
- break;
-
-#endif
-
- for (; pos < max_len; ++pos)
- if (a[pos] != b[pos])
- break;
-
- return pos;
-}
-
-/* Return the number of bytes before A and B that don't differ. If no
- * difference can be found in the first MAX_LEN characters, MAX_LEN will
- * be returned. Please note that A-MAX_LEN and B-MAX_LEN must both be
- * valid addresses.
- */
-static apr_size_t
-reverse_match_length(const char *a, const char *b, apr_size_t max_len)
-{
- apr_size_t pos = 0;
-
-#if SVN_UNALIGNED_ACCESS_IS_OK
-
- /* Chunky processing is so much faster ...
- *
- * We can't make this work on architectures that require aligned access
- * because A and B will probably have different alignment. So, skipping
- * the first few chars until alignment is reached is not an option.
- */
- for (pos = sizeof(apr_size_t); pos <= max_len; pos += sizeof(apr_size_t))
- if (*(const apr_size_t*)(a - pos) != *(const apr_size_t*)(b - pos))
- break;
-
- pos -= sizeof(apr_size_t);
-
-#endif
-
- /* If we find a mismatch at -pos, pos-1 characters matched.
- */
- while (++pos <= max_len)
- if (a[0-pos] != b[0-pos])
- return pos - 1;
-
- /* No mismatch found -> at least MAX_LEN matching chars.
- */
- return max_len;
-}
-
-
/* Try to find a match for the target data B in BLOCKS, and then
extend the match as long as data in A and B at the match position
continues to match. We set the position in A we ended up in (in
@@ -323,9 +258,9 @@ find_match(const struct blocks *blocks,
max_delta = asize - apos - MATCH_BLOCKSIZE < bsize - bpos - MATCH_BLOCKSIZE
? asize - apos - MATCH_BLOCKSIZE
: bsize - bpos - MATCH_BLOCKSIZE;
- delta = match_length(a + apos + MATCH_BLOCKSIZE,
- b + bpos + MATCH_BLOCKSIZE,
- max_delta);
+ delta = svn_cstring__match_length(a + apos + MATCH_BLOCKSIZE,
+ b + bpos + MATCH_BLOCKSIZE,
+ max_delta);
/* See if we can extend backwards (max MATCH_BLOCKSIZE-1 steps because A's
content has been sampled only every MATCH_BLOCKSIZE positions). */
@@ -362,7 +297,8 @@ store_delta_trailer(svn_txdelta__ops_bat
if (max_len == 0)
return;
- end_match = reverse_match_length(a + asize, b + bsize, max_len);
+ end_match = svn_cstring__reverse_match_length(a + asize, b + bsize,
+ max_len);
if (end_match <= 4)
end_match = 0;
@@ -414,7 +350,7 @@ compute_delta(svn_txdelta__ops_baton_t *
/* Optimization: directly compare window starts. If more than 4
* bytes match, we can immediately create a matching windows.
* Shorter sequences result in a net data increase. */
- lo = match_length(a, b, asize > bsize ? bsize : asize);
+ lo = svn_cstring__match_length(a, b, asize > bsize ? bsize : asize);
if ((lo > 4) || (lo == bsize))
{
svn_txdelta__insert_op(build_baton, svn_txdelta_source,
@@ -468,7 +404,8 @@ compute_delta(svn_txdelta__ops_baton_t *
{
/* the match borders on the previous op. Maybe, we found a
* match that is better than / overlapping the previous one. */
- apr_size_t len = reverse_match_length(a + apos, b + lo, apos < lo ? apos : lo);
+ apr_size_t len = svn_cstring__reverse_match_length
+ (a + apos, b + lo, apos < lo ? apos : lo);
if (len > 0)
{
len = svn_txdelta__remove_copy(build_baton, len);
Modified: subversion/branches/cache-server/subversion/libsvn_diff/diff_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_diff/diff_file.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_diff/diff_file.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_diff/diff_file.c Tue Oct 15 08:52:06 2013
@@ -166,26 +166,39 @@ read_chunk(apr_file_t *file, const char
static svn_error_t *
map_or_read_file(apr_file_t **file,
MMAP_T_PARAM(mm)
- char **buffer, apr_off_t *size,
+ char **buffer, apr_size_t *size_p,
const char *path, apr_pool_t *pool)
{
apr_finfo_t finfo;
apr_status_t rv;
+ apr_size_t size;
*buffer = NULL;
SVN_ERR(svn_io_file_open(file, path, APR_READ, APR_OS_DEFAULT, pool));
SVN_ERR(svn_io_file_info_get(&finfo, APR_FINFO_SIZE, *file, pool));
+ if (finfo.size > APR_SIZE_MAX)
+ {
+ return svn_error_createf(APR_ENOMEM, NULL,
+ _("File '%s' is too large to be read in "
+ "to memory"), path);
+ }
+
+ size = (apr_size_t) finfo.size;
#if APR_HAS_MMAP
- if (finfo.size > APR_MMAP_THRESHOLD)
+ if (size > APR_MMAP_THRESHOLD)
{
- rv = apr_mmap_create(mm, *file, 0, (apr_size_t) finfo.size,
- APR_MMAP_READ, pool);
+ rv = apr_mmap_create(mm, *file, 0, size, APR_MMAP_READ, pool);
if (rv == APR_SUCCESS)
{
*buffer = (*mm)->mm;
}
+ else
+ {
+ /* Clear *MM because output parameters are undefined on error. */
+ *mm = NULL;
+ }
/* On failure we just fall through and try reading the file into
* memory instead.
@@ -193,12 +206,11 @@ map_or_read_file(apr_file_t **file,
}
#endif /* APR_HAS_MMAP */
- if (*buffer == NULL && finfo.size > 0)
+ if (*buffer == NULL && size > 0)
{
- *buffer = apr_palloc(pool, (apr_size_t) finfo.size);
+ *buffer = apr_palloc(pool, size);
- SVN_ERR(svn_io_file_read_full2(*file, *buffer, (apr_size_t) finfo.size,
- NULL, NULL, pool));
+ SVN_ERR(svn_io_file_read_full2(*file, *buffer, size, NULL, NULL, pool));
/* Since we have the entire contents of the file we can
* close it now.
@@ -208,7 +220,7 @@ map_or_read_file(apr_file_t **file,
*file = NULL;
}
- *size = finfo.size;
+ *size_p = size;
return SVN_NO_ERROR;
}
@@ -634,7 +646,7 @@ find_identical_suffix(apr_off_t *suffix_
min_curp[0] += suffix_min_offset0;
/* Scan quickly by reading with machine-word granularity. */
- for (i = 0, can_read_word = TRUE; i < file_len; i++)
+ for (i = 0, can_read_word = TRUE; can_read_word && i < file_len; i++)
can_read_word = can_read_word
&& ( (file_for_suffix[i].curp + 1
- sizeof(apr_uintptr_t))
@@ -652,7 +664,7 @@ find_identical_suffix(apr_off_t *suffix_
if (contains_eol(chunk))
break;
- for (i = 1, is_match = TRUE; i < file_len; i++)
+ for (i = 1, is_match = TRUE; is_match && i < file_len; i++)
is_match = is_match
&& ( chunk
== *(const apr_uintptr_t *)
@@ -957,7 +969,7 @@ datasource_get_next_token(apr_uint32_t *
function.
When changing things here, make sure the whitespace settings are
- applied, or we mught not reach the exact suffix boundary as token
+ applied, or we might not reach the exact suffix boundary as token
boundary. */
SVN_ERR(read_chunk(file->file, file->path,
curp, length,
@@ -2360,7 +2372,7 @@ svn_diff_file_output_merge2(svn_stream_t
for (idx = 0; idx < 3; idx++)
{
- apr_off_t size;
+ apr_size_t size;
SVN_ERR(map_or_read_file(&file[idx],
MMAP_T_ARG(mm[idx])