You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/08/10 19:03:37 UTC
svn commit: r984122 [13/40] - in /subversion/branches/ignore-mergeinfo: ./
build/ build/ac-macros/ build/generator/ build/generator/swig/
build/generator/templates/ build/generator/util/ build/hudson/
build/hudson/jobs/ build/hudson/jobs/subversion-1.6...
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/client.h?rev=984122&r1=984121&r2=984122&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/client.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/client.h Tue Aug 10 17:03:06 2010
@@ -2,10 +2,10 @@
* client.h : shared stuff internal to the client library.
*
* ====================================================================
- * Licensed to the Subversion Corporation (SVN Corp.) under one
+ * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
- * regarding copyright ownership. The SVN Corp. licenses this file
+ * regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
@@ -77,9 +77,21 @@ svn_client__derive_location(const char *
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
-/* Get the repository URL and revision number for LOCAL_ABSPATH,
- which is sometimes the path's copyfrom info rather than its actual
- URL and revision. */
+/* Get the repository URL and revision number for LOCAL_ABSPATH and put them
+ in *URL and *REVNUM. REVNUM may be null, in which case it is ignored.
+
+ If PEG_REV_KIND is svn_opt_revision_working, then use the LOCAL_ABSPATH's
+ copyfrom info to populate *URL and *REVNUM.
+
+ If PEG_REV_KIND is svn_opt_revision_date or svn_opt_revision_head then
+ return SVN_ERR_CLIENT_BAD_REVISION.
+
+ If PEG_REV_KIND is svn_opt_revision_committed or svn_opt_revision_previous
+ then set *REVNUM to the last committed or previous revision respectively.
+
+ If PEG_REV_NUM is svn_opt_revision_unspecified, svn_opt_revision_number,
+ svn_opt_revision_base, or svn_opt_revision_working then set *REVNUM
+ to the base revision. */
svn_error_t *
svn_client__entry_location(const char **url,
svn_revnum_t *revnum,
@@ -263,14 +275,6 @@ svn_client__ra_session_from_path(svn_ra_
svn_client_ctx_t *ctx,
apr_pool_t *pool);
-/* Set *REL_PATH to a relative path which, when URI-encoded and joined
- with RA_SESSION's session url, will result in a string that matches URL. */
-svn_error_t *
-svn_client__path_relative_to_session(const char **rel_path,
- svn_ra_session_t *ra_session,
- const char *url,
- apr_pool_t *pool);
-
/* Ensure that RA_SESSION's session URL matches SESSION_URL,
reparenting that session if necessary. If reparenting occurs,
store the previous session URL in *OLD_SESSION_URL (so that if the
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/cmdline.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/cmdline.c?rev=984122&r1=984121&r2=984122&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/cmdline.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/cmdline.c Tue Aug 10 17:03:06 2010
@@ -2,10 +2,10 @@
* cmdline.c: command-line processing
*
* ====================================================================
- * Licensed to the Subversion Corporation (SVN Corp.) under one
+ * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
- * regarding copyright ownership. The SVN Corp. licenses this file
+ * regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
@@ -281,7 +281,9 @@ svn_client_args_to_target_array(apr_arra
* arguments.
*/
if (root_url == NULL)
- SVN_ERR(svn_client_root_url_from_path(&root_url, "", ctx, pool));
+ SVN_ERR_W(svn_client_root_url_from_path(&root_url, "", ctx, pool),
+ "Resolving '^/': no repository root found in the "
+ "target arguments or in the current directory");
*targets_p = apr_array_make(pool, output_targets->nelts,
sizeof(const char *));
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/commit.c?rev=984122&r1=984121&r2=984122&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/commit.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/commit.c Tue Aug 10 17:03:06 2010
@@ -2,10 +2,10 @@
* commit.c: wrappers around wc commit functionality.
*
* ====================================================================
- * Licensed to the Subversion Corporation (SVN Corp.) under one
+ * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
- * regarding copyright ownership. The SVN Corp. licenses this file
+ * regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
@@ -897,189 +897,6 @@ reconcile_errors(svn_error_t *commit_err
return err;
}
-/* Remove redundancies by removing duplicates from NONRECURSIVE_TARGETS,
- * and removing any target that either is, or is a descendant of, a path in
- * RECURSIVE_TARGETS. Return the result in *PUNIQUE_TARGETS.
- */
-static svn_error_t *
-remove_redundancies(apr_array_header_t **punique_targets,
- const apr_array_header_t *nonrecursive_targets,
- const apr_array_header_t *recursive_targets,
- apr_pool_t *pool)
-{
- apr_pool_t *temp_pool;
- apr_array_header_t *abs_recursive_targets = NULL;
- apr_hash_t *abs_targets;
- apr_array_header_t *rel_targets;
- int i;
-
- if ((nonrecursive_targets->nelts <= 0) || (! punique_targets))
- {
- /* No targets or no place to store our work means this function
- really has nothing to do. */
- if (punique_targets)
- *punique_targets = NULL;
- return SVN_NO_ERROR;
- }
-
- /* Initialize our temporary pool. */
- temp_pool = svn_pool_create(pool);
-
- /* Create our list of absolute paths for our "keepers" */
- abs_targets = apr_hash_make(temp_pool);
-
- /* Create our list of absolute paths for our recursive targets */
- if (recursive_targets)
- {
- abs_recursive_targets = apr_array_make(temp_pool,
- recursive_targets->nelts,
- sizeof(const char *));
-
- for (i = 0; i < recursive_targets->nelts; i++)
- {
- const char *rel_path =
- APR_ARRAY_IDX(recursive_targets, i, const char *);
- const char *abs_path;
-
- /* Get the absolute path for this target. */
- SVN_ERR(svn_dirent_get_absolute(&abs_path, rel_path, temp_pool));
-
- APR_ARRAY_PUSH(abs_recursive_targets, const char *) = abs_path;
- }
- }
-
- /* Create our list of untainted paths for our "keepers" */
- rel_targets = apr_array_make(pool, nonrecursive_targets->nelts,
- sizeof(const char *));
-
- /* For each target in our list we do the following:
-
- 1. Calculate its absolute path (ABS_PATH).
- 2. See if any of the keepers in RECURSIVE_TARGETS is a parent of, or
- is the same path as, ABS_PATH. If so, we ignore this
- target. If not, however, add this target's original path to
- REL_TARGETS. */
- for (i = 0; i < nonrecursive_targets->nelts; i++)
- {
- const char *rel_path = APR_ARRAY_IDX(nonrecursive_targets, i,
- const char *);
- const char *abs_path;
- int j;
- svn_boolean_t keep_me;
-
- /* Get the absolute path for this target. */
- SVN_ERR(svn_dirent_get_absolute(&abs_path, rel_path, temp_pool));
-
- /* For each keeper in ABS_TARGETS, see if this target is the
- same as or a child of that keeper. */
- keep_me = TRUE;
-
- if (abs_recursive_targets)
- {
- for (j = 0; j < abs_recursive_targets->nelts; j++)
- {
- const char *keeper = APR_ARRAY_IDX(abs_recursive_targets, j,
- const char *);
-
- /* Quit here if we find this path already in the keepers. */
- if (strcmp(keeper, abs_path) == 0)
- {
- keep_me = FALSE;
- break;
- }
-
- /* Quit here if this path is a child of one of the keepers. */
- if (svn_dirent_is_child(keeper, abs_path, temp_pool))
- {
- keep_me = FALSE;
- break;
- }
- }
- }
-
- /* If this is a new keeper, add its absolute path to ABS_TARGETS
- and its original path to REL_TARGETS. */
- if (keep_me
- && apr_hash_get(abs_targets, abs_path, APR_HASH_KEY_STRING) == NULL)
- {
- APR_ARRAY_PUSH(rel_targets, const char *) = rel_path;
- apr_hash_set(abs_targets, abs_path, APR_HASH_KEY_STRING, abs_path);
- }
- }
-
- /* Destroy our temporary pool. */
- svn_pool_destroy(temp_pool);
-
- /* Make sure we return the list of untainted keeper paths. */
- *punique_targets = rel_targets;
-
- return SVN_NO_ERROR;
-}
-
-/* Adjust relative targets. If there is an empty string in REL_TARGETS
- * get the actual target anchor point. It is likely that this is one dir up
- * from BASE_DIR, therefor we need to prepend the name part of the actual
- * target to all paths in REL_TARGETS. Return the new anchor in *PBASE_DIR,
- * and the adjusted relative paths in *PREL_TARGETS.
- */
-static svn_error_t *
-adjust_rel_targets(const char **pbase_dir,
- apr_array_header_t **prel_targets,
- svn_wc_context_t *wc_ctx,
- const char *base_dir,
- apr_array_header_t *rel_targets,
- apr_pool_t *pool)
-{
- const char *target;
- int i;
- svn_boolean_t anchor_one_up = FALSE;
- apr_array_header_t *new_rel_targets;
-
- for (i = 0; i < rel_targets->nelts; i++)
- {
- target = APR_ARRAY_IDX(rel_targets, i, const char *);
-
- if (target[0] == '\0')
- {
- anchor_one_up = TRUE;
- break;
- }
- }
-
- /* Default to not doing anything */
- new_rel_targets = rel_targets;
-
- if (anchor_one_up)
- {
- const char *parent_dir, *name;
-
- SVN_ERR(svn_wc_get_actual_target2(&parent_dir, &name, wc_ctx, base_dir,
- pool, pool));
-
- if (*name)
- {
- /* Our new "grandfather directory" is the parent directory
- of the former one. */
- base_dir = apr_pstrdup(pool, parent_dir);
-
- new_rel_targets = apr_array_make(pool, rel_targets->nelts,
- sizeof(name));
- for (i = 0; i < rel_targets->nelts; i++)
- {
- target = APR_ARRAY_IDX(rel_targets, i, const char *);
- target = svn_dirent_join(name, target, pool);
- APR_ARRAY_PUSH(new_rel_targets, const char *) = target;
- }
- }
- }
-
- *pbase_dir = base_dir;
- *prel_targets = new_rel_targets;
-
- return SVN_NO_ERROR;
-}
-
-
/* For all lock tokens in ALL_TOKENS for URLs under BASE_URL, add them
to a new hashtable allocated in POOL. *RESULT is set to point to this
new hash table. *RESULT will be keyed on const char * URI-decoded paths
@@ -1194,28 +1011,6 @@ commit_item_is_changed(void *baton, void
return SVN_NO_ERROR;
}
-struct lock_dirs_baton
-{
- svn_client_ctx_t *ctx;
- svn_wc_adm_access_t *base_dir_access;
- int levels_to_lock;
-};
-
-static svn_error_t *
-lock_dirs_for_commit(void *baton, void *this_item, apr_pool_t *pool)
-{
- struct lock_dirs_baton *btn = baton;
- svn_wc_adm_access_t *adm_access;
-
- return svn_wc__adm_open_in_context(&adm_access, btn->ctx->wc_ctx,
- *(const char **)this_item,
- TRUE, /* Write lock */
- btn->levels_to_lock,
- btn->ctx->cancel_func,
- btn->ctx->cancel_baton,
- pool);
-}
-
struct check_dir_delete_baton
{
svn_wc_adm_access_t *base_dir_access;
@@ -1307,9 +1102,6 @@ svn_client_commit4(svn_commit_info_t **c
const char *base_url;
const char *target;
apr_array_header_t *rel_targets;
- apr_array_header_t *dirs_to_lock;
- apr_array_header_t *dirs_to_lock_recursive;
- svn_boolean_t lock_base_dir_recursive = FALSE;
apr_hash_t *committables;
apr_hash_t *lock_tokens;
apr_hash_t *tempfiles = NULL;
@@ -1342,73 +1134,6 @@ svn_client_commit4(svn_commit_info_t **c
if (! base_dir)
goto cleanup;
- /* When svn_path_condense_targets() was written, we didn't have real
- * depths, we just had recursive / nonrecursive.
- *
- * Nowadays things are more complex. If depth == svn_depth_files,
- * for example, and two targets are "foo" and "foo/bar", then
- * ideally we should condense out "foo/bar" if it's a file and not
- * if it's a directory. And, of course, later when we get adm
- * access batons for the commit, we'd ideally lock directories to
- * precisely the depth required and no deeper.
- *
- * But for now we don't do that. Instead, we lock recursively from
- * base_dir, if depth indicates that we might need anything below
- * there (but note that above, we don't condense away targets that
- * need to be named explicitly when depth != svn_depth_infinity).
- *
- * Here's a case where this all matters:
- *
- * $ svn st -q
- * M A/D/G/rho
- * M iota
- * $ svn ci -m "log msg" --depth=immediates . A/D/G
- *
- * If we don't lock base_dir recursively, then it will get an error...
- *
- * subversion/libsvn_wc/lock.c:570: (apr_err=155004)
- * svn: Working copy '/blah/blah/blah/wc' locked
- * svn: run 'svn cleanup' to remove locks \
- * (type 'svn help cleanup' for details)
- *
- * ...because later (see dirs_to_lock_recursively and dirs_to_lock)
- * we'd call svn_wc_adm_open3() to get access objects for "" and
- * "A/D/G", but the request for "" would fail because base_dir_access
- * would already be open for that directory. (In that circumstance,
- * you're supposed to use svn_wc_adm_retrieve() instead; but it
- * would be clumsy to have a conditional path just to decide between
- * open3() and retrieve().)
- *
- * (Note that the results would be the same if even the working copy
- * were an explicit argument, e.g.:
- * 'svn ci -m "log msg" --depth=immediates wc wc/A/D/G'.)
- *
- * So we set lock_base_dir_recursive=TRUE now, and end up locking
- * more than we need to, but this keeps the code simple and correct.
- *
- * In an inspired bit of foresight, the adm locking code anticipated
- * the eventual addition of svn_depth_immediates, and allows us to
- * set the exact number of lock levels. So optimizing the code here
- * at least shouldn't require any changes to the adm locking system.
- */
- if (depth == svn_depth_files || depth == svn_depth_immediates)
- {
- for (i = 0; i < rel_targets->nelts; ++i)
- {
- const char *rel_target = APR_ARRAY_IDX(rel_targets, i, const char *);
-
- if (rel_target[0] == '\0')
- {
- lock_base_dir_recursive = TRUE;
- break;
- }
- }
- }
-
- /* Prepare an array to accumulate dirs to lock */
- dirs_to_lock = apr_array_make(pool, 1, sizeof(target));
- dirs_to_lock_recursive = apr_array_make(pool, 1, sizeof(target));
-
/* If we calculated only a base_dir and no relative targets, this
must mean that we are being asked to commit (effectively) a
single path. */
@@ -1436,134 +1161,17 @@ svn_client_commit4(svn_commit_info_t **c
target = svn_dirent_join(base_dir, name, pool);
SVN_ERR(svn_io_check_path(target, &kind, pool));
-
- /* If the final target is a dir, we want to recursively lock it */
- if (kind == svn_node_dir)
- {
- if (depth == svn_depth_infinity || depth == svn_depth_immediates)
- APR_ARRAY_PUSH(dirs_to_lock_recursive, const char *) = target;
- else
- APR_ARRAY_PUSH(dirs_to_lock, const char *) = target;
- }
}
- else
- {
- /* Unconditionally lock recursively down from base_dir. */
- lock_base_dir_recursive = TRUE;
- }
- }
- else if (! lock_base_dir_recursive)
- {
- apr_pool_t *subpool = svn_pool_create(pool);
-
- SVN_ERR(adjust_rel_targets(&base_dir, &rel_targets, ctx->wc_ctx,
- base_dir, rel_targets, pool));
-
- for (i = 0; i < rel_targets->nelts; i++)
- {
- svn_node_kind_t kind;
-
- svn_pool_clear(subpool);
-
- target = svn_dirent_join(base_dir,
- APR_ARRAY_IDX(rel_targets, i, const char *),
- subpool);
-
- SVN_ERR(svn_io_check_path(target, &kind, subpool));
-
- /* If the final target is a dir, we want to lock it */
- if (kind == svn_node_dir)
- {
- /* Notice how here we test infinity||immediates, but up
- in the call to svn_path_condense_targets(), we only
- tested depth==infinity. That's because condensation
- and adm lock acquisition serve different purposes. */
- if (depth == svn_depth_infinity || depth == svn_depth_immediates)
- APR_ARRAY_PUSH(dirs_to_lock_recursive,
- const char *) = apr_pstrdup(pool, target);
- else
- /* Don't lock if target is the base_dir, base_dir will be
- locked anyway and we can't lock it twice */
- if (strcmp(target, base_dir) != 0)
- APR_ARRAY_PUSH(dirs_to_lock,
- const char *) = apr_pstrdup(pool, target);
- }
-
- /* Now we need to iterate over the parent paths of this path
- adding them to the set of directories we want to lock.
- Do nothing if target is already the base_dir. */
- if (strcmp(target, base_dir) != 0)
- {
- target = svn_dirent_dirname(target, subpool);
-
- while (strcmp(target, base_dir) != 0)
- {
- const char *parent_dir;
-
- APR_ARRAY_PUSH(dirs_to_lock,
- const char *) = apr_pstrdup(pool, target);
-
- parent_dir = svn_dirent_dirname(target, subpool);
-
- if (strcmp(parent_dir, target) == 0)
- break; /* Reached root directory */
-
- target = parent_dir;
- }
- }
- }
-
- svn_pool_destroy(subpool);
}
SVN_ERR(svn_wc__adm_open_in_context(&base_dir_access,
ctx->wc_ctx,
base_dir,
TRUE, /* Write lock */
- lock_base_dir_recursive ? -1 : 0,
+ -1, /* recursive lock */
ctx->cancel_func, ctx->cancel_baton,
pool));
- if (!lock_base_dir_recursive)
- {
- apr_array_header_t *unique_dirs_to_lock;
- struct lock_dirs_baton btn;
-
- /* Sort the paths in a depth-last directory-ish order. */
- qsort(dirs_to_lock->elts, dirs_to_lock->nelts,
- dirs_to_lock->elt_size, svn_sort_compare_paths);
- qsort(dirs_to_lock_recursive->elts, dirs_to_lock_recursive->nelts,
- dirs_to_lock_recursive->elt_size, svn_sort_compare_paths);
-
- /* Remove any duplicates */
- SVN_ERR(svn_path_remove_redundancies(&unique_dirs_to_lock,
- dirs_to_lock_recursive,
- pool));
- dirs_to_lock_recursive = unique_dirs_to_lock;
-
- /* Remove dirs and descendants from dirs_to_lock if there is
- any ancestor in dirs_to_lock_recursive */
- SVN_ERR(remove_redundancies(&unique_dirs_to_lock,
- dirs_to_lock,
- dirs_to_lock_recursive,
- pool));
- dirs_to_lock = unique_dirs_to_lock;
-
- btn.base_dir_access = base_dir_access;
- btn.ctx = ctx;
- btn.levels_to_lock = 0;
- /* First lock all the dirs to be locked non-recursively */
- if (dirs_to_lock)
- SVN_ERR(svn_iter_apr_array(NULL, dirs_to_lock,
- lock_dirs_for_commit, &btn, pool));
-
- /* Lock the rest of the targets (recursively) */
- btn.levels_to_lock = -1;
- if (dirs_to_lock_recursive)
- SVN_ERR(svn_iter_apr_array(NULL, dirs_to_lock_recursive,
- lock_dirs_for_commit, &btn, pool));
- }
-
/* One day we might support committing from multiple working copies, but
we don't yet. This check ensures that we don't silently commit a
subset of the targets.
@@ -1662,7 +1270,7 @@ svn_client_commit4(svn_commit_info_t **c
/* Perform the commit. */
cmt_err = svn_client__do_commit(base_url, commit_items, editor, edit_baton,
- notify_prefix, &tempfiles, &checksums, ctx,
+ notify_prefix, &tempfiles, &checksums, ctx,
pool);
/* Handle a successful commit. */
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/commit_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/commit_util.c?rev=984122&r1=984121&r2=984122&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/commit_util.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/commit_util.c Tue Aug 10 17:03:06 2010
@@ -2,10 +2,10 @@
* commit_util.c: Driver for the WC commit process.
*
* ====================================================================
- * Licensed to the Subversion Corporation (SVN Corp.) under one
+ * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
- * regarding copyright ownership. The SVN Corp. licenses this file
+ * regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
@@ -430,6 +430,9 @@ harvest_committables(apr_hash_t *committ
svn_dirent_local_style(path, scratch_pool));
}
+ if (entry->file_external_path && copy_mode)
+ return SVN_NO_ERROR;
+
if (entry->kind == svn_node_dir)
{
/* Read the dir's own entries for use when recursing. */
@@ -796,7 +799,7 @@ harvest_committables(apr_hash_t *committ
ctx->wc_ctx,
this_abspath,
iterpool));
-
+
if (obstructed)
{
/* A missing, schedule-delete child dir is
@@ -1021,18 +1024,21 @@ svn_client__harvest_committables(apr_has
{
const char *parent_abspath = svn_dirent_dirname(target_abspath,
subpool);
- const svn_wc_entry_t *p_entry;
+ svn_boolean_t is_added;
- SVN_ERR(svn_wc__maybe_get_entry(&p_entry, ctx->wc_ctx,
- parent_abspath, svn_node_dir,
- FALSE, FALSE, subpool, subpool));
- if (! p_entry)
- return svn_error_createf
- (SVN_ERR_WC_CORRUPT, NULL,
- _("'%s' is scheduled for addition within unversioned parent"),
- svn_dirent_local_style(target, pool));
- if ((p_entry->schedule == svn_wc_schedule_add)
- || (p_entry->schedule == svn_wc_schedule_replace))
+ err = svn_wc__node_is_status_added(&is_added, ctx->wc_ctx,
+ parent_abspath, subpool);
+ if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ {
+ svn_error_clear(err);
+ return svn_error_createf(
+ SVN_ERR_WC_CORRUPT, NULL,
+ _("'%s' is scheduled for addition within unversioned parent"),
+ svn_dirent_local_style(target, pool));
+ }
+ SVN_ERR(err);
+
+ if (is_added)
{
/* Copy the parent and target into pool; subpool
lasts only for this loop iteration, and we check
@@ -1363,7 +1369,7 @@ do_item_commit(void **dir_baton,
SVN_ERR(svn_wc_prop_get2(&propval, ctx->wc_ctx, local_abspath,
SVN_PROP_MIME_TYPE, pool, pool));
-
+
if (propval)
notify->mime_type = propval->data;
}
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/compat_providers.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/compat_providers.c?rev=984122&r1=984121&r2=984122&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/compat_providers.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/compat_providers.c Tue Aug 10 17:03:06 2010
@@ -2,10 +2,10 @@
* compat_providers.c: wrapper providers backwards compatibility
*
* ====================================================================
- * Licensed to the Subversion Corporation (SVN Corp.) under one
+ * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
- * regarding copyright ownership. The SVN Corp. licenses this file
+ * regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/copy.c?rev=984122&r1=984121&r2=984122&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/copy.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/copy.c Tue Aug 10 17:03:06 2010
@@ -2,10 +2,10 @@
* copy.c: copy/move wrappers around wc 'copy' functionality.
*
* ====================================================================
- * Licensed to the Subversion Corporation (SVN Corp.) under one
+ * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
- * regarding copyright ownership. The SVN Corp. licenses this file
+ * regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
@@ -73,7 +73,7 @@
*TARGET_MERGEINFO. ADM_ACCESS may be NULL, if SRC_PATH_OR_URL is an
URL. If NO_REPOS_ACCESS is set, this function is disallowed from
consulting the repository about anything. RA_SESSION may be NULL but
- only if NO_REPOS_ACCESS is true. */
+ only if NO_REPOS_ACCESS is true. */
static svn_error_t *
calculate_target_mergeinfo(svn_ra_session_t *ra_session,
apr_hash_t **target_mergeinfo,
@@ -119,20 +119,22 @@ calculate_target_mergeinfo(svn_ra_sessio
if (! locally_added)
{
- const char *mergeinfo_path;
-
if (! no_repos_access)
{
- /* Fetch any existing (explicit) mergeinfo. */
- SVN_ERR(svn_client__path_relative_to_root(&mergeinfo_path,
- ctx->wc_ctx, src_url,
- entry ? entry->repos : NULL,
- FALSE, ra_session,
- pool, pool));
+ /* Fetch any existing (explicit) mergeinfo. We'll temporarily
+ reparent to the target URL here, just to keep the code simple.
+ We could, as an alternative, first see if the target URL was a
+ child of the session URL and use the relative "remainder",
+ falling back to this reparenting as necessary. */
+ const char *old_session_url = NULL;
+ SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url,
+ ra_session, src_url, pool));
SVN_ERR(svn_client__get_repos_mergeinfo(ra_session, &src_mergeinfo,
- mergeinfo_path, src_revnum,
+ "", src_revnum,
svn_mergeinfo_inherited,
TRUE, pool));
+ if (old_session_url)
+ SVN_ERR(svn_ra_reparent(ra_session, old_session_url, pool));
}
else
{
@@ -194,25 +196,30 @@ get_copy_pair_ancestors(const apr_array_
{
apr_pool_t *subpool = svn_pool_create(pool);
const char *first_dst;
+ const char *first_src;
const char *top_dst;
+ svn_boolean_t src_is_url;
+ svn_boolean_t dst_is_url;
char *top_src;
int i;
/* Because all the destinations are in the same directory, we can easily
determine their common ancestor. */
first_dst = APR_ARRAY_IDX(copy_pairs, 0, svn_client__copy_pair_t *)->dst;
+ dst_is_url = svn_path_is_url(first_dst);
+
if (copy_pairs->nelts == 1)
top_dst = apr_pstrdup(subpool, first_dst);
- else if (svn_path_is_url(first_dst))
- top_dst = svn_uri_dirname(first_dst, subpool);
else
- top_dst = svn_dirent_dirname(first_dst, subpool);
+ top_dst = dst_is_url ? svn_uri_dirname(first_dst, subpool)
+ : svn_dirent_dirname(first_dst, subpool);
/* Sources can came from anywhere, so we have to actually do some
work for them. */
- top_src = apr_pstrdup(subpool,
- APR_ARRAY_IDX(copy_pairs, 0,
- svn_client__copy_pair_t *)->src);
+ first_src = APR_ARRAY_IDX(copy_pairs, 0,
+ svn_client__copy_pair_t *)->src;
+ src_is_url = svn_path_is_url(first_src);
+ top_src = apr_pstrdup(subpool, first_src);
for (i = 1; i < copy_pairs->nelts; i++)
{
/* We don't need to clear the subpool here for several reasons:
@@ -226,7 +233,11 @@ get_copy_pair_ancestors(const apr_array_
*/
const svn_client__copy_pair_t *pair =
APR_ARRAY_IDX(copy_pairs, i, svn_client__copy_pair_t *);
- top_src = svn_path_get_longest_ancestor(top_src, pair->src, subpool);
+
+ top_src =
+ src_is_url
+ ? svn_uri_get_longest_ancestor(top_src, pair->src, subpool)
+ : svn_dirent_get_longest_ancestor(top_src, pair->src, subpool);
}
if (src_ancestor)
@@ -236,7 +247,10 @@ get_copy_pair_ancestors(const apr_array_
*dst_ancestor = apr_pstrdup(pool, top_dst);
if (common_ancestor)
- *common_ancestor = svn_path_get_longest_ancestor(top_src, top_dst, pool);
+ *common_ancestor =
+ src_is_url
+ ? svn_uri_get_longest_ancestor(top_src, top_dst, pool)
+ : svn_dirent_get_longest_ancestor(top_src, top_dst, pool);
svn_pool_destroy(subpool);
@@ -266,7 +280,8 @@ do_wc_to_wc_copies(const apr_array_heade
/* ### If we didn't potentially use DST_ACCESS as the SRC_ACCESS, we
### could use a read lock here. */
SVN_ERR(svn_wc__adm_open_in_context(&dst_access, ctx->wc_ctx, dst_parent,
- TRUE, 0, ctx->cancel_func, ctx->cancel_baton, pool));
+ TRUE, -1, ctx->cancel_func, ctx->cancel_baton,
+ pool));
for (i = 0; i < copy_pairs->nelts; i++)
{
@@ -315,8 +330,12 @@ do_wc_to_wc_moves(const apr_array_header
for (i = 0; i < copy_pairs->nelts; i++)
{
- svn_wc_adm_access_t *src_access, *dst_access;
+ svn_wc_adm_access_t *src_access;
+ svn_wc_adm_access_t *dst_access;
+ svn_boolean_t close_dst_access = FALSE;
+ svn_boolean_t close_src_access = FALSE;
const char *src_parent;
+ const char *src_parent_abspath;
const char *dst_abspath;
const char *dst_parent_abspath;
@@ -328,43 +347,61 @@ do_wc_to_wc_moves(const apr_array_header
if (ctx->cancel_func)
SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
- svn_dirent_split(pair->src, &src_parent, NULL, iterpool);
-
- SVN_ERR(svn_wc__adm_open_in_context(&src_access, ctx->wc_ctx, src_parent,
- TRUE, pair->src_kind == svn_node_dir ? -1 : 0,
- ctx->cancel_func, ctx->cancel_baton,
- iterpool));
-
+ src_parent = svn_dirent_dirname(pair->src, iterpool);
+ SVN_ERR(svn_dirent_get_absolute(&src_parent_abspath, src_parent,
+ iterpool));
SVN_ERR(svn_dirent_get_absolute(&dst_parent_abspath, pair->dst_parent,
iterpool));
- /* Need to avoid attempting to open the same dir twice when source
- and destination overlap. */
- if (strcmp(src_parent, pair->dst_parent) == 0)
- {
+ /* We now need to open the right combination of batons.
+ Four cases:
+ 1) src_parent == dst_parent
+ 2) src_parent is parent of dst_parent
+ 3) dst_parent is parent of src_parent
+ 4) src_parent and dst_parent are disjoint */
+ if (strcmp(src_parent_abspath, dst_parent_abspath) == 0)
+ {
+ SVN_ERR(svn_wc__adm_open_in_context(&src_access, ctx->wc_ctx,
+ src_parent, TRUE, -1,
+ ctx->cancel_func,
+ ctx->cancel_baton, iterpool));
dst_access = src_access;
+ close_src_access = TRUE;
+ }
+ else if (svn_dirent_is_child(src_parent_abspath, dst_parent_abspath,
+ iterpool))
+ {
+ SVN_ERR(svn_wc__adm_open_in_context(&src_access, ctx->wc_ctx,
+ src_parent, TRUE, -1,
+ ctx->cancel_func,
+ ctx->cancel_baton, iterpool));
+ SVN_ERR(svn_wc_adm_retrieve(&dst_access, src_access,
+ pair->dst_parent, iterpool));
+ close_src_access = TRUE;
+ }
+ else if (svn_dirent_is_child(dst_parent_abspath, src_parent_abspath,
+ iterpool))
+ {
+ SVN_ERR(svn_wc__adm_open_in_context(&dst_access, ctx->wc_ctx,
+ pair->dst_parent, TRUE, -1,
+ ctx->cancel_func,
+ ctx->cancel_baton, iterpool));
+ SVN_ERR(svn_wc_adm_retrieve(&src_access, dst_access, src_parent,
+ iterpool));
+ close_dst_access = TRUE;
}
else
{
- const char *src_parent_abs;
-
- SVN_ERR(svn_dirent_get_absolute(&src_parent_abs, src_parent,
- iterpool));
- if ((pair->src_kind == svn_node_dir)
- && (svn_dirent_is_child(src_parent_abs, dst_parent_abspath,
- iterpool)))
- {
- SVN_ERR(svn_wc_adm_retrieve(&dst_access, src_access,
- pair->dst_parent, iterpool));
- }
- else
- {
- SVN_ERR(svn_wc__adm_open_in_context(&dst_access, ctx->wc_ctx,
- pair->dst_parent, TRUE, 0,
- ctx->cancel_func,
- ctx->cancel_baton,
- iterpool));
- }
+ SVN_ERR(svn_wc__adm_open_in_context(&src_access, ctx->wc_ctx,
+ src_parent, TRUE, -1,
+ ctx->cancel_func,
+ ctx->cancel_baton, iterpool));
+ SVN_ERR(svn_wc__adm_open_in_context(&dst_access, ctx->wc_ctx,
+ pair->dst_parent, TRUE, -1,
+ ctx->cancel_func,
+ ctx->cancel_baton, iterpool));
+ close_dst_access = TRUE;
+ close_src_access = TRUE;
}
/* Perform the copy and then the delete. */
@@ -383,9 +420,10 @@ do_wc_to_wc_moves(const apr_array_header
ctx->notify_func2, ctx->notify_baton2,
iterpool));
- if (dst_access != src_access)
+ if (close_dst_access)
SVN_ERR(svn_wc_adm_close2(dst_access, iterpool));
- SVN_ERR(svn_wc_adm_close2(src_access, iterpool));
+ if (close_src_access)
+ SVN_ERR(svn_wc_adm_close2(src_access, iterpool));
}
svn_pool_destroy(iterpool);
@@ -585,13 +623,13 @@ path_driver_cb_func(void **dir_baton,
}
-/* Starting with the path DIR relative to the root of RA_SESSION, work up
- * through DIR's parents until an existing node is found. Push each
- * nonexistent path onto the array NEW_DIRS, allocating in POOL.
- * Raise an error if the existing node is not a directory.
- *
- * ### The multiple requests for HEAD revision (SVN_INVALID_REVNUM) make
- * this implementation susceptible to race conditions. */
+/* Starting with the path DIR relative to the RA_SESSION's session
+ URL, work up through DIR's parents until an existing node is found.
+ Push each nonexistent path onto the array NEW_DIRS, allocating in
+ POOL. Raise an error if the existing node is not a directory.
+
+ ### Multiple requests for HEAD (SVN_INVALID_REVNUM) make this
+ ### implementation susceptible to race conditions. */
static svn_error_t *
find_absent_parents1(svn_ra_session_t *ra_session,
const char *dir,
@@ -609,7 +647,7 @@ find_absent_parents1(svn_ra_session_t *r
svn_pool_clear(iterpool);
APR_ARRAY_PUSH(new_dirs, const char *) = dir;
- svn_dirent_split(dir, &dir, NULL, pool);
+ dir = svn_dirent_dirname(dir, pool);
SVN_ERR(svn_ra_check_path(ra_session, dir, SVN_INVALID_REVNUM,
&kind, iterpool));
@@ -617,22 +655,23 @@ find_absent_parents1(svn_ra_session_t *r
if (kind != svn_node_dir)
return svn_error_createf(SVN_ERR_FS_ALREADY_EXISTS, NULL,
- _("Path '%s' already exists, but is not a directory"),
- dir);
+ _("Path '%s' already exists, but is not a "
+ "directory"), dir);
svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
-/* Starting with the URL *TOP_DST_URL which is also the root of RA_SESSION,
- * work up through its parents until an existing node is found. Push each
- * nonexistent URL onto the array NEW_DIRS, allocating in POOL.
- * Raise an error if the existing node is not a directory.
- *
- * Set *TOP_DST_URL and the RA session's root to the existing node's URL.
- *
- * ### The multiple requests for HEAD revision (SVN_INVALID_REVNUM) make
- * this implementation susceptible to race conditions. */
+/* Starting with the URL *TOP_DST_URL which is also the root of
+ RA_SESSION, work up through its parents until an existing node is
+ found. Push each nonexistent URL onto the array NEW_DIRS,
+ allocating in POOL. Raise an error if the existing node is not a
+ directory.
+
+ Set *TOP_DST_URL and the RA session's root to the existing node's URL.
+
+ ### Multiple requests for HEAD (SVN_INVALID_REVNUM) make this
+ ### implementation susceptible to race conditions. */
static svn_error_t *
find_absent_parents2(svn_ra_session_t *ra_session,
const char **top_dst_url,
@@ -673,13 +712,15 @@ repos_to_repos_copy(svn_commit_info_t **
svn_boolean_t is_move,
apr_pool_t *pool)
{
+ svn_error_t *err;
apr_array_header_t *paths = apr_array_make(pool, 2 * copy_pairs->nelts,
sizeof(const char *));
apr_hash_t *action_hash = apr_hash_make(pool);
apr_array_header_t *path_infos;
- const char *top_url, *message, *repos_root;
- svn_revnum_t youngest;
- svn_ra_session_t *ra_session;
+ const char *top_url, *top_url_all, *top_url_dst;
+ const char *message, *repos_root, *ignored_url;
+ svn_revnum_t youngest = SVN_INVALID_REVNUM;
+ svn_ra_session_t *ra_session = NULL;
const svn_delta_editor_t *editor;
void *edit_baton;
void *commit_baton;
@@ -687,25 +728,89 @@ repos_to_repos_copy(svn_commit_info_t **
apr_array_header_t *new_dirs = NULL;
apr_hash_t *commit_revprops;
int i;
- svn_error_t *err;
+ svn_client__copy_pair_t *first_pair =
+ APR_ARRAY_IDX(copy_pairs, 0, svn_client__copy_pair_t *);
+
+ /* Open an RA session to the first copy pair's destination. We'll
+ be verifying that every one of our copy source and destination
+ URLs is or is beneath this sucker's repository root URL as a form
+ of a cheap(ish) sanity check. */
+ SVN_ERR(svn_client__open_ra_session_internal(&ra_session, first_pair->src,
+ NULL, NULL, FALSE, TRUE,
+ ctx, pool));
+ SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root, pool));
- /* Create a path_info struct for each src/dst pair, and initialize it. */
+ /* Verify that sources and destinations are all at or under
+ REPOS_ROOT. While here, create a path_info struct for each
+ src/dst pair and initialize portions of it with normalized source
+ location information. */
path_infos = apr_array_make(pool, copy_pairs->nelts,
sizeof(path_driver_info_t *));
for (i = 0; i < copy_pairs->nelts; i++)
{
path_driver_info_t *info = apr_pcalloc(pool, sizeof(*info));
+ svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
+ svn_client__copy_pair_t *);
+ apr_hash_t *mergeinfo;
+ svn_opt_revision_t *src_rev, *ignored_rev, dead_end_rev;
+ dead_end_rev.kind = svn_opt_revision_unspecified;
+
+ /* Are the source and destination URLs at or under REPOS_ROOT? */
+ if (! (svn_uri_is_ancestor(repos_root, pair->src)
+ && svn_uri_is_ancestor(repos_root, pair->dst)))
+ return svn_error_create
+ (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+ _("Source and destination URLs appear not to all point to the "
+ "same repository."));
+
+ /* Resolve revision keywords and such into real revision number,
+ passing NULL for the path (to ensure error if trying to get a
+ revision based on the working copy). */
+ SVN_ERR(svn_client__get_revision_number(&pair->src_revnum, &youngest,
+ ctx->wc_ctx, NULL,
+ ra_session,
+ &pair->src_op_revision, pool));
+
+ /* Run the history function to get the source's URL in the
+ operational revision. */
+ SVN_ERR(svn_client__ensure_ra_session_url(&ignored_url, ra_session,
+ pair->src, pool));
+ SVN_ERR(svn_client__repos_locations(&pair->src, &src_rev,
+ &ignored_url, &ignored_rev,
+ ra_session,
+ pair->src, &pair->src_peg_revision,
+ &pair->src_op_revision,
+ &dead_end_rev, ctx, pool));
+
+ /* Go ahead and grab mergeinfo from the source, too. */
+ SVN_ERR(svn_client__ensure_ra_session_url(&ignored_url, ra_session,
+ pair->src, pool));
+ SVN_ERR(calculate_target_mergeinfo(ra_session, &mergeinfo, NULL, pair->src,
+ pair->src_revnum, FALSE, ctx, pool));
+ if (mergeinfo)
+ SVN_ERR(svn_mergeinfo_to_string(&info->mergeinfo, mergeinfo, pool));
+
+ /* Plop an INFO structure onto our array thereof. */
+ info->src_url = pair->src;
+ info->src_revnum = pair->src_revnum;
info->resurrection = FALSE;
APR_ARRAY_PUSH(path_infos, path_driver_info_t *) = info;
}
- /* We have to open our session to the longest path common to all
- SRC_URLS and DST_URLS in the repository so we can do existence
- checks on all paths, and so we can operate on all paths in the
- case of a move. */
- get_copy_pair_ancestors(copy_pairs, NULL, NULL, &top_url, pool);
-
- /* Check each src/dst pair for resurrection. */
+ /* If this is a move, we have to open our session to the longest
+ path common to all SRC_URLS and DST_URLS in the repository so we
+ can do existence checks on all paths, and so we can operate on
+ all paths in the case of a move. But if this is *not* a move,
+ then opening our session at the longest path common to sources
+ *and* destinations might be an optimization when the user is
+ authorized to access all that stuff, but could cause the
+ operation to fail altogether otherwise. See issue #3242. */
+ get_copy_pair_ancestors(copy_pairs, NULL, &top_url_dst, &top_url_all, pool);
+ top_url = is_move ? top_url_all : top_url_dst;
+
+ /* Check each src/dst pair for resurrection, and verify that TOP_URL
+ is anchored high enough to cover all the editor_t activities
+ required for this operation. */
for (i = 0; i < copy_pairs->nelts; i++)
{
svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
@@ -713,97 +818,103 @@ repos_to_repos_copy(svn_commit_info_t **
path_driver_info_t *info = APR_ARRAY_IDX(path_infos, i,
path_driver_info_t *);
+ /* Source and destination are the same? It's a resurrection. */
if (strcmp(pair->src, pair->dst) == 0)
- {
- info->resurrection = TRUE;
+ info->resurrection = TRUE;
- /* Special edge-case! (issue #683) If you're resurrecting a
- deleted item like this: 'svn cp -rN src_URL dst_URL', then
- it's possible for src_URL == dst_URL == top_url. In this
- situation, we want to open an RA session to be at least the
- *parent* of all three. */
- if (strcmp(pair->src, top_url) == 0)
- {
- top_url = svn_uri_dirname(top_url, pool);
- }
+ /* We need to add each dst_URL, and (in a move) we'll need to
+ delete each src_URL. Our selection of TOP_URL so far ensures
+ that all our destination URLs (and source URLs, for moves)
+ are at least as deep as TOP_URL, but we need to make sure
+ that TOP_URL is an *ancestor* of all our to-be-edited paths.
+
+ Issue #683 is demonstrates this scenario. If you're
+ resurrecting a deleted item like this: 'svn cp -rN src_URL
+ dst_URL', then src_URL == dst_URL == top_url. In this
+ situation, we want to open an RA session to be at least the
+ *parent* of all three. */
+ if ((strcmp(top_url, pair->dst) == 0)
+ && (strcmp(top_url, repos_root) != 0))
+ {
+ top_url = svn_uri_dirname(top_url, pool);
}
- }
-
- /* Open an RA session for the URL. Note that we don't have a local
- directory, nor a place to put temp files. */
- err = svn_client__open_ra_session_internal(&ra_session, top_url,
- NULL, NULL, FALSE, TRUE,
- ctx, pool);
-
- /* If the two URLs appear not to be in the same repository, then
- top_url will be empty and the call to svn_ra_open3()
- above will have failed. Below we check for that, and propagate a
- descriptive error back to the user.
-
- Ideally, we'd contact the repositories and compare their UUIDs to
- determine whether or not src and dst are in the same repository,
- instead of depending on an essentially textual comparison.
- However, it is simpler to assume that if someone is using the
- same repository, then they will use the same hostname/path to
- refer to it both times. Conversely, if the repositories are
- different, then they can't share a non-empty prefix, so top_url
- would still be "" and svn_ra_get_library() would still error.
- Thus we can get this check without extra network turnarounds to
- fetch the UUIDs.
- */
- if (err)
- {
- if ((err->apr_err == SVN_ERR_RA_ILLEGAL_URL)
- && ((top_url == NULL) || (top_url[0] == '\0')))
+ if (is_move
+ && (strcmp(top_url, pair->src) == 0)
+ && (strcmp(top_url, repos_root) != 0))
{
- svn_client__copy_pair_t *first_pair =
- APR_ARRAY_IDX(copy_pairs, 0, svn_client__copy_pair_t *);
- svn_error_clear(err);
-
- return svn_error_createf
- (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
- _("Source and dest appear not to be in the same repository "
- "(src: '%s'; dst: '%s')"),
- first_pair->src, first_pair->dst);
+ top_url = svn_uri_dirname(top_url, pool);
}
- else
- return svn_error_return(err);
}
- /* Make a list in NEW_DIRS of the parent directories of the destination
- that don't yet exist. We do not have to worry about
- reparenting the ra session because top_url is a common ancestor of the
- destination and sources. The sources exist, so therefore top_url must
- also exist. */
+ /* Point the RA session to our current TOP_URL. */
+ SVN_ERR(svn_client__ensure_ra_session_url(&ignored_url, ra_session,
+ top_url, pool));
+
+ /* If we're allowed to create nonexistent parent directories of our
+ destinations, then make a list in NEW_DIRS of the parent
+ directories of the destination that don't yet exist. */
if (make_parents)
{
- svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, 0,
- svn_client__copy_pair_t *);
const char *dir;
new_dirs = apr_array_make(pool, 0, sizeof(const char *));
- dir = svn_uri_is_child(top_url, svn_uri_dirname(pair->dst, pool),
- pool);
- /* Imagine a situation where the user tries to copy an existing source
- directory to nonexistent directory with --parents options specified:
-
- svn copy --parents URL/src URL/dst
+ /* If this is a move, TOP_URL is at least the common ancestor of
+ all the paths (sources and destinations) involved. Assuming
+ the sources exist (which is fair, because if they don't, this
+ whole operation will fail anyway), TOP_URL must also exist.
+ So it's the paths between TOP_URL and the destinations which
+ we have to check for existence. But here, we take advantage
+ of the knowledge of our caller. We know that if there are
+ multiple copy/move operations being requested, then the
+ destinations of the copies/moves will all be siblings of one
+ another. Therefore, we need only to check for the
+ nonexistent paths between TOP_URL and *one* of our
+ destinations to find nonexistent parents of all of them. */
+ if (is_move)
+ {
+ /* Imagine a situation where the user tries to copy an
+ existing source directory to nonexistent directory with
+ --parents options specified:
+
+ svn copy --parents URL/src URL/dst
+
+ where src exists and dst does not. The svn_uri_dirname()
+ call above will produce a string equivalent to TOP_URL,
+ which means svn_uri_is_child() will return NULL. In this
+ case, do not try to add dst to the NEW_DIRS list since it
+ will be added to the commit items array later in this
+ function. */
+ dir = svn_uri_is_child(top_url,
+ svn_uri_dirname(first_pair->dst, pool),
+ pool);
+ if (dir)
+ SVN_ERR(find_absent_parents1(ra_session,
+ svn_path_uri_decode(dir, pool),
+ new_dirs, pool));
+ }
+ /* If, however, this is *not* a move, TOP_URL only points to the
+ common ancestor of our destination path(s), or possibly one
+ level higher. We'll need to do an existence crawl toward the
+ root of the repository, starting with one of our destinations
+ (see "... take advantage of the knowledge of our caller ..."
+ above), and possibly adjusting TOP_URL as we go. */
+ else
+ {
+ apr_array_header_t *new_urls =
+ apr_array_make(pool, 0, sizeof(const char *));
+ SVN_ERR(find_absent_parents2(ra_session, &top_url, new_urls, pool));
- where src exists and dst does not. The svn_uri_dirname() call above
- will produce a string equivalent to top_url, which means
- svn_uri_is_child() will return NULL. In this case, do not try to add
- dst to the new_dirs list since it will be added to the commit items
- array later in this function. */
-
- if (dir)
- SVN_ERR(find_absent_parents1(ra_session,
- svn_path_uri_decode(dir, pool),
- new_dirs, pool));
+ /* Convert absolute URLs into URLs relative to TOP_URL. */
+ for (i = 0; i < new_urls->nelts; i++)
+ {
+ const char *new_url = APR_ARRAY_IDX(new_urls, i, const char *);
+ dir = svn_uri_is_child(top_url, new_url, pool);
+ APR_ARRAY_PUSH(new_dirs, const char *) = dir ? dir : "";
+ }
+ }
}
- SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root, pool));
-
/* For each src/dst pair, check to see if that SRC_URL is a child of
the DST_URL (excepting the case where DST_URL is the repo root).
If it is, and the parent of DST_URL is the current TOP_URL, then we
@@ -816,90 +927,80 @@ repos_to_repos_copy(svn_commit_info_t **
path_driver_info_t *info = APR_ARRAY_IDX(path_infos, i,
path_driver_info_t *);
- if (strcmp(pair->dst, repos_root) != 0
- && svn_uri_is_child(pair->dst, pair->src, pool) != NULL)
+ if ((strcmp(pair->dst, repos_root) != 0)
+ && (svn_uri_is_child(pair->dst, pair->src, pool) != NULL))
{
info->resurrection = TRUE;
top_url = svn_uri_dirname(top_url, pool);
-
SVN_ERR(svn_ra_reparent(ra_session, top_url, pool));
}
}
- /* Fetch the youngest revision. */
- SVN_ERR(svn_ra_get_latest_revnum(ra_session, &youngest, pool));
-
+ /* Get the portions of the SRC and DST URLs that are relative to
+ TOP_URL (URI-decoding them while we're at it), verify that the
+ source exists and the proposed destination does not, and toss
+ what we've learned into the INFO array. (For copies -- that is,
+ non-moves -- the relative source URL NULL because it isn't a
+ child of the TOP_URL at all. That's okay, we'll deal with
+ it.) */
for (i = 0; i < copy_pairs->nelts; i++)
{
- svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
- svn_client__copy_pair_t *);
- path_driver_info_t *info = APR_ARRAY_IDX(path_infos, i,
- path_driver_info_t *);
+ svn_client__copy_pair_t *pair =
+ APR_ARRAY_IDX(copy_pairs, i, svn_client__copy_pair_t *);
+ path_driver_info_t *info =
+ APR_ARRAY_IDX(path_infos, i, path_driver_info_t *);
svn_node_kind_t dst_kind;
const char *src_rel, *dst_rel;
- svn_opt_revision_t *new_rev, *ignored_rev, dead_end_rev;
- const char *ignored_url;
-
- /* Pass NULL for the path, to ensure error if trying to get a
- revision based on the working copy. */
- SVN_ERR(svn_client__get_revision_number(&pair->src_revnum, NULL,
- ctx->wc_ctx, NULL,
- ra_session,
- &pair->src_op_revision, pool));
-
- info->src_revnum = pair->src_revnum;
-
- dead_end_rev.kind = svn_opt_revision_unspecified;
-
- /* Run the history function to get the object's url in the operational
- revision. */
- SVN_ERR(svn_client__repos_locations(&pair->src, &new_rev,
- &ignored_url, &ignored_rev,
- NULL,
- pair->src, &pair->src_peg_revision,
- &pair->src_op_revision,
- &dead_end_rev, ctx, pool));
- /* Get the portions of the SRC and DST URLs that are relative to
- TOP_URL, and URI-decode those sections. */
src_rel = svn_uri_is_child(top_url, pair->src, pool);
if (src_rel)
- src_rel = svn_path_uri_decode(src_rel, pool);
+ {
+ src_rel = svn_path_uri_decode(src_rel, pool);
+ SVN_ERR(svn_ra_check_path(ra_session, src_rel, pair->src_revnum,
+ &info->src_kind, pool));
+ }
+ else if (strcmp(pair->src, top_url) == 0)
+ {
+ if (is_move)
+ return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+ _("Cannot move URL '%s' into itself"),
+ pair->src);
+ src_rel = "";
+ SVN_ERR(svn_ra_check_path(ra_session, src_rel, pair->src_revnum,
+ &info->src_kind, pool));
+ }
else
- src_rel = "";
+ {
+ const char *old_url = NULL;
+
+ src_rel = NULL;
+ SVN_ERR_ASSERT(! is_move);
+
+ SVN_ERR(svn_client__ensure_ra_session_url(&old_url, ra_session,
+ pair->src, pool));
+ SVN_ERR(svn_ra_check_path(ra_session, "", pair->src_revnum,
+ &info->src_kind, pool));
+ SVN_ERR(svn_ra_reparent(ra_session, old_url, pool));
+ }
+ if (info->src_kind == svn_node_none)
+ return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
+ _("Path '%s' does not exist in revision %ld"),
+ pair->src, pair->src_revnum);
+ /* Figure out the basename that will result from this operation,
+ and ensure that we aren't trying to overwrite existing paths. */
dst_rel = svn_uri_is_child(top_url, pair->dst, pool);
if (dst_rel)
dst_rel = svn_path_uri_decode(dst_rel, pool);
else
dst_rel = "";
-
- /* We can't move something into itself, period. */
- if (svn_path_is_empty(src_rel) && is_move)
- return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
- _("Cannot move URL '%s' into itself"),
- pair->src);
-
- /* Verify that SRC_URL exists in the repository. */
- SVN_ERR(svn_ra_check_path(ra_session, src_rel, pair->src_revnum,
- &info->src_kind, pool));
- if (info->src_kind == svn_node_none)
- return svn_error_createf
- (SVN_ERR_FS_NOT_FOUND, NULL,
- _("Path '%s' does not exist in revision %ld"),
- pair->src, pair->src_revnum);
-
- /* Figure out the basename that will result from this operation. */
- SVN_ERR(svn_ra_check_path(ra_session, dst_rel, youngest, &dst_kind,
- pool));
+ SVN_ERR(svn_ra_check_path(ra_session, dst_rel, youngest,
+ &dst_kind, pool));
if (dst_kind != svn_node_none)
- {
- /* We disallow the overwriting of existing paths. */
- return svn_error_createf(SVN_ERR_FS_ALREADY_EXISTS, NULL,
- _("Path '%s' already exists"), dst_rel);
- }
+ return svn_error_createf(SVN_ERR_FS_ALREADY_EXISTS, NULL,
+ _("Path '%s' already exists"), dst_rel);
- info->src_url = pair->src;
+ /* More info for our INFO structure. */
info->src_path = src_rel;
info->dst_path = dst_rel;
}
@@ -975,17 +1076,11 @@ repos_to_repos_copy(svn_commit_info_t **
}
}
- /* Then, copy destinations, and possibly move sources. */
+ /* Then our copy destinations and move sources (if any). */
for (i = 0; i < path_infos->nelts; i++)
{
path_driver_info_t *info = APR_ARRAY_IDX(path_infos, i,
path_driver_info_t *);
- apr_hash_t *mergeinfo;
- SVN_ERR(calculate_target_mergeinfo(ra_session, &mergeinfo, NULL,
- info->src_url, info->src_revnum,
- FALSE, ctx, pool));
- if (mergeinfo)
- SVN_ERR(svn_mergeinfo_to_string(&info->mergeinfo, mergeinfo, pool));
APR_ARRAY_PUSH(paths, const char *) = info->dst_path;
if (is_move && (! info->resurrection))
@@ -1040,7 +1135,7 @@ wc_to_repos_copy(svn_commit_info_t **com
apr_pool_t *pool)
{
const char *message;
- const char *top_src_path, *top_dst_url, *repos_root;
+ const char *top_src_path, *top_dst_url;
svn_ra_session_t *ra_session;
const svn_delta_editor_t *editor;
void *edit_baton;
@@ -1107,13 +1202,7 @@ wc_to_repos_copy(svn_commit_info_t **com
if (make_parents)
{
new_dirs = apr_array_make(pool, 0, sizeof(const char *));
-
- /* Starting at TOP_DST_URL which is also the session root, work up the
- * directory hierarchy until an existing node is found. Push each
- * nonexistent URL onto the array NEW_DIRS. Leave TOP_DST_URL and the
- * RA session parented at the existing node; error if it isn't a dir. */
SVN_ERR(find_absent_parents2(ra_session, &top_dst_url, new_dirs, pool));
- /* ### SVN_ERR(svn_ra_reparent(ra_session, top_dst_url, pool)); */
}
/* Figure out the basename that will result from each copy and check to make
@@ -1227,11 +1316,6 @@ wc_to_repos_copy(svn_commit_info_t **com
}
}
- /* Reparent the ra_session to repos_root. So that 'svn_ra_get_log'
- on paths relative to repos_root would work fine. */
- SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root, pool));
- SVN_ERR(svn_ra_reparent(ra_session, repos_root, pool));
-
/* ### TODO: This extra loop would be unnecessary if this code lived
### in svn_client__get_copy_committables(), which is incidentally
### only used above (so should really be in this source file). */
@@ -1423,8 +1507,8 @@ repos_to_wc_copy_single(svn_client__copy
svn_io_file_del_on_pool_cleanup, pool,
pool));
- SVN_ERR(svn_client__path_relative_to_session(&src_rel, ra_session,
- pair->src, pool));
+ SVN_ERR(svn_ra_get_path_relative_to_session(ra_session, &src_rel,
+ pair->src, pool));
SVN_ERR(svn_ra_get_file(ra_session, src_rel, src_revnum, fstream,
&real_rev, &new_props, pool));
SVN_ERR(svn_stream_close(fstream));
@@ -1544,8 +1628,8 @@ repos_to_wc_copy(const apr_array_header_
svn_pool_clear(iterpool);
/* Next, make sure that the path exists in the repository. */
- SVN_ERR(svn_client__path_relative_to_session(&src_rel, ra_session,
- pair->src, iterpool));
+ SVN_ERR(svn_ra_get_path_relative_to_session(ra_session, &src_rel,
+ pair->src, iterpool));
SVN_ERR(svn_ra_check_path(ra_session, src_rel, pair->src_revnum,
&pair->src_kind, pool));
if (pair->src_kind == svn_node_none)
@@ -1589,7 +1673,7 @@ repos_to_wc_copy(const apr_array_header_
/* Probe the wc at the longest common dst ancestor. */
SVN_ERR(svn_wc__adm_probe_in_context(&adm_access, ctx->wc_ctx, top_dst_path,
- TRUE, 0, ctx->cancel_func,
+ TRUE, -1, ctx->cancel_func,
ctx->cancel_baton, pool));
/* We've already checked for physical obstruction by a working file.
@@ -1704,35 +1788,22 @@ try_copy(svn_commit_info_t **commit_info
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
- apr_array_header_t *copy_pairs =
+ apr_array_header_t *copy_pairs =
apr_array_make(pool, sources->nelts,
sizeof(svn_client__copy_pair_t *));
svn_boolean_t srcs_are_urls, dst_is_url;
int i;
- /* Check to see if the supplied peg revisions make sense. */
- for (i = 0; i < sources->nelts; i++)
- {
- svn_client_copy_source_t *source =
- ((svn_client_copy_source_t **) (sources->elts))[i];
-
- if (svn_path_is_url(source->path)
- && (SVN_CLIENT__REVKIND_NEEDS_WC(source->peg_revision->kind)))
- return svn_error_create
- (SVN_ERR_CLIENT_BAD_REVISION, NULL,
- _("Revision type requires a working copy path, not a URL"));
- }
-
- /* Are either of our paths URLs?
- * Just check the first src_path. If there are more than one, we'll check
- * for homogeneity among them down below. */
+ /* Are either of our paths URLs? Just check the first src_path. If
+ there are more than one, we'll check for homogeneity among them
+ down below. */
srcs_are_urls = svn_path_is_url(APR_ARRAY_IDX(sources, 0,
svn_client_copy_source_t *)->path);
dst_is_url = svn_path_is_url(dst_path_in);
- /* If we have multiple source paths, it implies the dst_path is a directory
- * we are moving or copying into. Populate the dst_paths array to contain
- * a destination path for each of the source paths. */
+ /* If we have multiple source paths, it implies the dst_path is a
+ directory we are moving or copying into. Populate the COPY_PAIRS
+ array to contain a destination path for each of the source paths. */
if (sources->nelts > 1)
{
apr_pool_t *iterpool = svn_pool_create(pool);
@@ -1768,7 +1839,7 @@ try_copy(svn_commit_info_t **commit_info
(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
_("Cannot mix repository and working copy sources"));
- pair->dst = dst_is_url
+ pair->dst = dst_is_url
? svn_uri_join(dst_path_in, src_basename, pool)
: svn_dirent_join(dst_path_in, src_basename, pool);
APR_ARRAY_PUSH(copy_pairs, svn_client__copy_pair_t *) = pair;
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/ctx.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/ctx.c?rev=984122&r1=984121&r2=984122&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/ctx.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/ctx.c Tue Aug 10 17:03:06 2010
@@ -2,10 +2,10 @@
* ctx.c: initialization function for client context
*
* ====================================================================
- * Licensed to the Subversion Corporation (SVN Corp.) under one
+ * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
- * regarding copyright ownership. The SVN Corp. licenses this file
+ * regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/delete.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/delete.c?rev=984122&r1=984121&r2=984122&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/delete.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/delete.c Tue Aug 10 17:03:06 2010
@@ -2,10 +2,10 @@
* delete.c: wrappers around wc delete functionality.
*
* ====================================================================
- * Licensed to the Subversion Corporation (SVN Corp.) under one
+ * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
- * regarding copyright ownership. The SVN Corp. licenses this file
+ * regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
@@ -140,7 +140,7 @@ delete_urls(svn_commit_info_t **commit_i
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
- svn_ra_session_t *ra_session;
+ svn_ra_session_t *ra_session = NULL;
const svn_delta_editor_t *editor;
void *edit_baton;
void *commit_baton;
@@ -194,29 +194,47 @@ delete_urls(svn_commit_info_t **commit_i
SVN_ERR(svn_client__ensure_revprop_table(&commit_revprops, revprop_table,
log_msg, ctx, pool));
- /* Open an RA session for the URL. Note that we don't have a local
- directory, nor a place to put temp files. */
- SVN_ERR(svn_client__open_ra_session_internal(&ra_session, common, NULL,
- NULL, FALSE, TRUE, ctx, pool));
-
/* Verify that each thing to be deleted actually exists (to prevent
the creation of a revision that has no changes, since the
- filesystem allows for no-op deletes). */
+ filesystem allows for no-op deletes). While here, we'll
+ URI-decode our targets. */
for (i = 0; i < targets->nelts; i++)
{
const char *path = APR_ARRAY_IDX(targets, i, const char *);
+ const char *item_url;
+
svn_pool_clear(subpool);
+ item_url = svn_path_url_add_component2(common, path, subpool);
path = svn_path_uri_decode(path, pool);
APR_ARRAY_IDX(targets, i, const char *) = path;
- SVN_ERR(svn_ra_check_path(ra_session, path, SVN_INVALID_REVNUM,
+
+ /* If we've not yet done so, open an RA session for the
+ URL. Note that we don't have a local directory, nor a place
+ to put temp files. Otherwise, reparent our existing
+ session. */
+ if (! ra_session)
+ {
+ SVN_ERR(svn_client__open_ra_session_internal(&ra_session, item_url,
+ NULL, NULL, FALSE,
+ TRUE, ctx, pool));
+ }
+ else
+ {
+ SVN_ERR(svn_ra_reparent(ra_session, item_url, subpool));
+ }
+
+ SVN_ERR(svn_ra_check_path(ra_session, "", SVN_INVALID_REVNUM,
&kind, subpool));
if (kind == svn_node_none)
return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
"URL '%s' does not exist",
- svn_dirent_local_style(path, pool));
+ svn_dirent_local_style(item_url, pool));
}
svn_pool_destroy(subpool);
+ /* Reparent the RA_session to the common parent of our deletees. */
+ SVN_ERR(svn_ra_reparent(ra_session, common, pool));
+
/* Fetch RA commit editor */
SVN_ERR(svn_client__commit_get_baton(&commit_baton, commit_info_p, pool));
SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton,
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/deprecated.c?rev=984122&r1=984121&r2=984122&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/deprecated.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/deprecated.c Tue Aug 10 17:03:06 2010
@@ -3,10 +3,10 @@
* "we can't lose 'em, but we can shun 'em!"
*
* ====================================================================
- * Licensed to the Subversion Corporation (SVN Corp.) under one
+ * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
- * regarding copyright ownership. The SVN Corp. licenses this file
+ * regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
@@ -169,7 +169,7 @@ svn_client_blame4(const char *target,
apr_pool_t *pool)
{
struct blame_receiver_wrapper_baton2 baton;
-
+
baton.receiver = receiver;
baton.baton = receiver_baton;
@@ -284,10 +284,10 @@ wrapped_receiver(void *baton,
static void
wrap_pre_blame3_receiver(svn_client_blame_receiver_t *receiver,
- void **receiver_baton,
- apr_pool_t *pool)
+ void **receiver_baton,
+ apr_pool_t *pool)
{
- if (strlen(APR_EOL_STR) > 1)
+ if (sizeof(APR_EOL_STR) == 3)
{
struct wrapped_receiver_baton_s *b = apr_palloc(pool,sizeof(*b));
@@ -899,6 +899,24 @@ svn_client_diff_summarize_peg(const char
/*** From export.c ***/
svn_error_t *
+svn_client_export4(svn_revnum_t *result_rev,
+ const char *from,
+ const char *to,
+ const svn_opt_revision_t *peg_revision,
+ const svn_opt_revision_t *revision,
+ svn_boolean_t overwrite,
+ svn_boolean_t ignore_externals,
+ svn_depth_t depth,
+ const char *native_eol,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ return svn_client_export5(result_rev, from, to, peg_revision, revision,
+ overwrite, ignore_externals, FALSE, depth,
+ native_eol, ctx, pool);
+}
+
+svn_error_t *
svn_client_export3(svn_revnum_t *result_rev,
const char *from,
const char *to,
@@ -1825,7 +1843,7 @@ svn_client_url_from_path(const char **ur
apr_pool_t *pool)
{
svn_client_ctx_t *ctx;
-
+
SVN_ERR(svn_client_create_context(&ctx, pool));
return svn_client_url_from_path2(url, path_or_url, ctx, pool, pool);
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_client/diff.c?rev=984122&r1=984121&r2=984122&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_client/diff.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_client/diff.c Tue Aug 10 17:03:06 2010
@@ -2,10 +2,10 @@
* diff.c: comparing
*
* ====================================================================
- * Licensed to the Subversion Corporation (SVN Corp.) under one
+ * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
- * regarding copyright ownership. The SVN Corp. licenses this file
+ * regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
@@ -222,7 +222,7 @@ display_prop_diffs(const apr_array_heade
for (i = 0; i < propchanges->nelts; i++)
{
- const char *header_fmt;
+ const char *action;
const svn_string_t *original_value;
const svn_prop_t *propchange =
&APR_ARRAY_IDX(propchanges, i, svn_prop_t);
@@ -246,11 +246,11 @@ display_prop_diffs(const apr_array_heade
continue;
if (! original_value)
- header_fmt = _("Added: %s%s");
+ action = _("Added");
else if (! propchange->value)
- header_fmt = _("Deleted: %s%s");
+ action = _("Deleted");
else
- header_fmt = _("Modified: %s%s");
+ action = _("Modified");
/* Lazily print the property diff header. */
if (!header_printed)
@@ -267,7 +267,7 @@ display_prop_diffs(const apr_array_heade
header_printed = TRUE;
}
- SVN_ERR(file_printf_from_utf8(file, encoding, header_fmt,
+ SVN_ERR(file_printf_from_utf8(file, encoding, "%s: %s%s", action,
propchange->name, APR_EOL_STR));
if (strcmp(propchange->name, SVN_PROP_MERGEINFO) == 0)
@@ -283,7 +283,7 @@ display_prop_diffs(const apr_array_heade
{
svn_stream_t *os = svn_stream_from_aprfile2(file, TRUE, pool);
svn_diff_t *diff;
- svn_diff_file_options_t options;
+ svn_diff_file_options_t options = { 0 };
const svn_string_t *tmp;
const svn_string_t *orig;
const svn_string_t *val;
@@ -889,7 +889,7 @@ diff_dir_closed(const char *local_dir_ab
associated url in *URL, allocated in RESULT_POOL. If ABSPATH_OR_URL is
*already* a URL, that's fine, return ABSPATH_OR_URL allocated in
RESULT_POOL.
-
+
Use SCRATCH_POOL for temporary allocations. */
static svn_error_t *
convert_to_url(const char **url,
@@ -1791,13 +1791,6 @@ svn_client_diff_peg5(const apr_array_hea
struct diff_cmd_baton diff_cmd_baton;
svn_wc_diff_callbacks4_t diff_callbacks;
- if (svn_path_is_url(path) &&
- (start_revision->kind == svn_opt_revision_base
- || end_revision->kind == svn_opt_revision_base) )
- return svn_error_create(SVN_ERR_CLIENT_BAD_REVISION, NULL,
- _("Revision type requires a working copy "
- "path, not a URL"));
-
/* fill diff_param */
diff_params.path1 = path;
diff_params.revision1 = start_revision;