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 2012/05/14 16:07:47 UTC
svn commit: r1338209 [1/4] - in /subversion/branches/ev2-export: ./
build/ac-macros/ subversion/bindings/javahl/src/org/apache/subversion/javahl/
subversion/include/ subversion/include/private/ subversion/libsvn_client/
subversion/libsvn_ra_serf/ subve...
Author: hwright
Date: Mon May 14 14:07:45 2012
New Revision: 1338209
URL: http://svn.apache.org/viewvc?rev=1338209&view=rev
Log:
On the ev2-export branch:
Bring up-to-date with trunk.
Modified:
subversion/branches/ev2-export/ (props changed)
subversion/branches/ev2-export/build/ac-macros/swig.m4
subversion/branches/ev2-export/configure.ac
subversion/branches/ev2-export/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java
subversion/branches/ev2-export/subversion/include/private/svn_client_private.h
subversion/branches/ev2-export/subversion/include/private/svn_wc_private.h
subversion/branches/ev2-export/subversion/include/svn_wc.h
subversion/branches/ev2-export/subversion/include/svn_xml.h
subversion/branches/ev2-export/subversion/libsvn_client/commit_util.c
subversion/branches/ev2-export/subversion/libsvn_client/externals.c
subversion/branches/ev2-export/subversion/libsvn_client/merge.c
subversion/branches/ev2-export/subversion/libsvn_client/mergeinfo.c
subversion/branches/ev2-export/subversion/libsvn_client/switch.c
subversion/branches/ev2-export/subversion/libsvn_client/update.c
subversion/branches/ev2-export/subversion/libsvn_client/util.c
subversion/branches/ev2-export/subversion/libsvn_ra_serf/blame.c
subversion/branches/ev2-export/subversion/libsvn_ra_serf/commit.c
subversion/branches/ev2-export/subversion/libsvn_ra_serf/get_deleted_rev.c
subversion/branches/ev2-export/subversion/libsvn_ra_serf/getdate.c
subversion/branches/ev2-export/subversion/libsvn_ra_serf/getlocations.c
subversion/branches/ev2-export/subversion/libsvn_ra_serf/getlocationsegments.c
subversion/branches/ev2-export/subversion/libsvn_ra_serf/getlocks.c
subversion/branches/ev2-export/subversion/libsvn_ra_serf/locks.c
subversion/branches/ev2-export/subversion/libsvn_ra_serf/log.c
subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c
subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c
subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h
subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c
subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c
subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c
subversion/branches/ev2-export/subversion/libsvn_ra_serf/xml.c
subversion/branches/ev2-export/subversion/libsvn_subr/lock.c
subversion/branches/ev2-export/subversion/libsvn_subr/xml.c
subversion/branches/ev2-export/subversion/libsvn_wc/conflicts.c
subversion/branches/ev2-export/subversion/libsvn_wc/node.c
subversion/branches/ev2-export/subversion/libsvn_wc/questions.c
subversion/branches/ev2-export/subversion/libsvn_wc/status.c
subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.c
subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.h
subversion/branches/ev2-export/subversion/libsvn_wc/workqueue.h
subversion/branches/ev2-export/subversion/svn/conflict-callbacks.c
subversion/branches/ev2-export/subversion/svn/resolve-cmd.c
subversion/branches/ev2-export/subversion/svnserve/serve.c
subversion/branches/ev2-export/subversion/tests/cmdline/davautocheck.sh
subversion/branches/ev2-export/subversion/tests/cmdline/lock_tests.py
subversion/branches/ev2-export/subversion/tests/cmdline/special_tests.py
subversion/branches/ev2-export/subversion/tests/cmdline/svntest/err.py
subversion/branches/ev2-export/tools/dev/gen-py-errors.py
subversion/branches/ev2-export/tools/dist/release.py
Propchange: subversion/branches/ev2-export/
------------------------------------------------------------------------------
Merged /subversion/trunk:r1336971-1338207
Modified: subversion/branches/ev2-export/build/ac-macros/swig.m4
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/build/ac-macros/swig.m4?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/build/ac-macros/swig.m4 (original)
+++ subversion/branches/ev2-export/build/ac-macros/swig.m4 Mon May 14 14:07:45 2012
@@ -187,7 +187,7 @@ AC_DEFUN(SVN_FIND_SWIG,
for var_name in arch archdir CC LDSHARED DLEXT LIBS LIBRUBYARG \
rubyhdrdir sitedir sitelibdir sitearchdir libdir
do
- rbconfig_tmp=`$rbconfig "print Config::CONFIG@<:@'$var_name'@:>@"`
+ rbconfig_tmp=`$rbconfig "print RbConfig::CONFIG@<:@'$var_name'@:>@"`
eval "rbconfig_$var_name=\"$rbconfig_tmp\""
done
Modified: subversion/branches/ev2-export/configure.ac
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/configure.ac?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/configure.ac (original)
+++ subversion/branches/ev2-export/configure.ac Mon May 14 14:07:45 2012
@@ -1184,12 +1184,12 @@ if test "$RUBY" != "none"; then
AC_PATH_PROGS(RDOC, rdoc rdoc1.8 rdoc18, none)
fi
AC_CACHE_CHECK([for Ruby major version], [svn_cv_ruby_major],[
- svn_cv_ruby_major="`$RUBY -rrbconfig -e 'print Config::CONFIG.fetch(%q(MAJOR))'`"
+ svn_cv_ruby_major="`$RUBY -rrbconfig -e 'print RbConfig::CONFIG.fetch(%q(MAJOR))'`"
])
RUBY_MAJOR="$svn_cv_ruby_major"
AC_CACHE_CHECK([for Ruby minor version], [svn_cv_ruby_minor],[
- svn_cv_ruby_minor="`$RUBY -rrbconfig -e 'print Config::CONFIG.fetch(%q(MINOR))'`"
+ svn_cv_ruby_minor="`$RUBY -rrbconfig -e 'print RbConfig::CONFIG.fetch(%q(MINOR))'`"
])
RUBY_MINOR="$svn_cv_ruby_minor"
Modified: subversion/branches/ev2-export/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java (original)
+++ subversion/branches/ev2-export/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java Mon May 14 14:07:45 2012
@@ -547,7 +547,10 @@ public class ClientNotifyInformation ext
skip_conflicted ("skipped conflicted path"),
/** The lock on a file was removed during update */
- update_broken_lock ("broken lock removed");
+ update_broken_lock ("broken lock removed"),
+
+ /** Operation failed because a node is obstructed */
+ failed_obstructed ("failed by obstruction");
/**
Modified: subversion/branches/ev2-export/subversion/include/private/svn_client_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/include/private/svn_client_private.h?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/include/private/svn_client_private.h (original)
+++ subversion/branches/ev2-export/subversion/include/private/svn_client_private.h Mon May 14 14:07:45 2012
@@ -144,9 +144,33 @@ svn_client__youngest_common_ancestor(con
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
-/* Set *ORIGIN_P to the origin of the WC node at WC_ABSPATH. If the node
+/* Get the repository location of the base node at LOCAL_ABSPATH.
+ *
+ * A pathrev_t wrapper around svn_wc__node_get_base().
+ *
+ * Set *BASE_P to the location that this node was checked out at or last
+ * updated/switched to, regardless of any uncommitted changes (delete,
+ * replace and/or copy-here/move-here).
+ *
+ * If there is no base node at LOCAL_ABSPATH (such as when there is a
+ * locally added/copied/moved-here node that is not part of a replace),
+ * set *BASE_P to NULL.
+ */
+svn_error_t *
+svn_client__wc_node_get_base(svn_client__pathrev_t **base_p,
+ const char *wc_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/* Get the original location of the WC node at LOCAL_ABSPATH.
+ *
+ * A pathrev_t wrapper around svn_wc__node_get_origin().
+ *
+ * Set *ORIGIN_P to the origin of the WC node at WC_ABSPATH. If the node
* is a local copy, give the copy-from location. If the node is locally
- * added or deleted, set *ORIGIN_P to NULL. */
+ * added or deleted, set *ORIGIN_P to NULL.
+ */
svn_error_t *
svn_client__wc_node_get_origin(svn_client__pathrev_t **origin_p,
const char *wc_abspath,
Modified: subversion/branches/ev2-export/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/include/private/svn_wc_private.h?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/include/private/svn_wc_private.h (original)
+++ subversion/branches/ev2-export/subversion/include/private/svn_wc_private.h Mon May 14 14:07:45 2012
@@ -1051,23 +1051,14 @@ svn_wc__get_tmpdir(const char **tmpdir_a
* ### it's caller will eventually move into a wc and maybe wc_db api.
*/
svn_error_t *
-svn_wc__node_get_commit_status(svn_node_kind_t *kind,
- svn_boolean_t *added,
+svn_wc__node_get_commit_status(svn_boolean_t *added,
svn_boolean_t *deleted,
- svn_boolean_t *replaced,
- svn_boolean_t *not_present,
- svn_boolean_t *excluded,
+ svn_boolean_t *is_replace_root,
svn_boolean_t *is_op_root,
- svn_boolean_t *symlink,
svn_revnum_t *revision,
- const char **repos_relpath,
svn_revnum_t *original_revision,
const char **original_repos_relpath,
- svn_boolean_t *conflicted,
- const char **changelist,
- svn_boolean_t *props_mod,
svn_boolean_t *update_root,
- const char **lock_token,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *result_pool,
Modified: subversion/branches/ev2-export/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/include/svn_wc.h?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/include/svn_wc.h (original)
+++ subversion/branches/ev2-export/subversion/include/svn_wc.h Mon May 14 14:07:45 2012
@@ -1223,7 +1223,11 @@ typedef enum svn_wc_notify_action_t
/** Just the lock on a file was removed during update.
* @since New in 1.8. */
- svn_wc_notify_update_broken_lock
+ svn_wc_notify_update_broken_lock,
+
+ /** Operation failed because a node is obstructed.
+ * @since New in 1.8. */
+ svn_wc_notify_failed_obstruction
} svn_wc_notify_action_t;
@@ -2623,24 +2627,22 @@ svn_wc_has_binary_prop(svn_boolean_t *ha
* with regard to the base revision, else set @a *modified_p to zero.
* @a local_abspath is the absolute path to the file.
*
- * If @a force_comparison is @c TRUE, this function will not allow
- * early return mechanisms that avoid actual content comparison.
- * Instead, if there is a text base, a full byte-by-byte comparison
- * will be done, and the entry checksum verified as well. (This means
- * that if the text base is much longer than the working file, every
- * byte of the text base will still be examined.)
+ * This function uses some heuristics to avoid byte-by-byte comparisons
+ * against the base text (eg. file size and its modification time).
*
* If @a local_abspath does not exist, consider it unmodified. If it exists
* but is not under revision control (not even scheduled for
* addition), return the error #SVN_ERR_ENTRY_NOT_FOUND.
*
+ * @a unused is ignored.
+ *
* @since New in 1.7.
*/
svn_error_t *
svn_wc_text_modified_p2(svn_boolean_t *modified_p,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
- svn_boolean_t force_comparison,
+ svn_boolean_t unused,
apr_pool_t *scratch_pool);
/** Similar to svn_wc_text_modified_p2(), but with a relative path and
Modified: subversion/branches/ev2-export/subversion/include/svn_xml.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/include/svn_xml.h?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/include/svn_xml.h (original)
+++ subversion/branches/ev2-export/subversion/include/svn_xml.h Mon May 14 14:07:45 2012
@@ -228,7 +228,7 @@ svn_xml_signal_bailout(svn_error_t *erro
*/
const char *
svn_xml_get_attr_value(const char *name,
- const char **atts);
+ const char *const *atts);
Modified: subversion/branches/ev2-export/subversion/libsvn_client/commit_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/commit_util.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/commit_util.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/commit_util.c Mon May 14 14:07:45 2012
@@ -266,80 +266,6 @@ look_up_committable(svn_client__committa
apr_hash_get(committables->by_path, path, APR_HASH_KEY_STRING);
}
-/* Helper for harvest_committables().
- * If ENTRY is a dir, return an SVN_ERR_WC_FOUND_CONFLICT error when
- * encountering a tree-conflicted immediate child node. However, do
- * not consider immediate children that are outside the bounds of DEPTH.
- *
- * TODO ### WC_CTX and LOCAL_ABSPATH ...
- * ENTRY, DEPTH, CHANGELISTS and POOL are the same ones
- * originally received by harvest_committables().
- *
- * Tree-conflicts information is stored in the victim's immediate parent.
- * In some cases of an absent tree-conflicted victim, the tree-conflict
- * information in its parent dir is the only indication that the node
- * is under version control. This function is necessary for this
- * particular case. In all other cases, this simply bails out a little
- * bit earlier. */
-static svn_error_t *
-bail_on_tree_conflicted_children(svn_wc_context_t *wc_ctx,
- const char *local_abspath,
- svn_node_kind_t kind,
- svn_depth_t depth,
- apr_hash_t *changelists,
- svn_wc_notify_func2_t notify_func,
- void *notify_baton,
- apr_pool_t *pool)
-{
- apr_hash_t *conflicts;
- apr_hash_index_t *hi;
-
- if ((depth == svn_depth_empty)
- || (kind != svn_node_dir))
- /* There can't possibly be tree-conflicts information here. */
- return SVN_NO_ERROR;
-
- SVN_ERR(svn_wc__get_all_tree_conflicts(&conflicts, wc_ctx, local_abspath,
- pool, pool));
- if (!conflicts)
- return SVN_NO_ERROR;
-
- for (hi = apr_hash_first(pool, conflicts); hi; hi = apr_hash_next(hi))
- {
- const svn_wc_conflict_description2_t *conflict =
- svn__apr_hash_index_val(hi);
-
- if ((conflict->node_kind == svn_node_dir) &&
- (depth == svn_depth_files))
- continue;
-
- /* So we've encountered a conflict that is included in DEPTH.
- Bail out. But if there are CHANGELISTS, avoid bailing out
- on an item that doesn't match the CHANGELISTS. */
- if (!svn_wc__changelist_match(wc_ctx, local_abspath, changelists, pool))
- continue;
-
- /* At this point, a conflict was found, and either there were no
- changelists, or the changelists matched. Bail out already! */
-
- if (notify_func != NULL)
- {
- notify_func(notify_baton,
- svn_wc_create_notify(local_abspath,
- svn_wc_notify_failed_conflict,
- pool),
- pool);
- }
-
- return svn_error_createf(
- SVN_ERR_WC_FOUND_CONFLICT, NULL,
- _("Aborting commit: '%s' remains in conflict"),
- svn_dirent_local_style(conflict->local_abspath, pool));
- }
-
- return SVN_NO_ERROR;
-}
-
/* Helper function for svn_client__harvest_committables().
* Determine whether we are within a tree-conflicted subtree of the
* working copy and return an SVN_ERR_WC_FOUND_CONFLICT error if so. */
@@ -430,19 +356,43 @@ bail_on_tree_conflicted_ancestor(svn_wc_
Any items added to COMMITTABLES are allocated from the COMITTABLES
hash pool, not POOL. SCRATCH_POOL is used for temporary allocations. */
+
+struct harvest_baton
+{
+ /* Static data */
+ const char *root_abspath;
+ svn_client__committables_t *committables;
+ apr_hash_t *lock_tokens;
+ const char *commit_relpath; /* Valid for the harvest root */
+ svn_depth_t depth;
+ svn_boolean_t just_locked;
+ apr_hash_t *changelists;
+ apr_hash_t *danglers;
+ svn_client__check_url_kind_t check_url_func;
+ void *check_url_baton;
+ svn_wc_notify_func2_t notify_func;
+ void *notify_baton;
+ svn_wc_context_t *wc_ctx;
+ apr_pool_t *result_pool;
+
+ /* Harvester state */
+ const char *skip_below_abspath; /* If non-NULL, skip everything below */
+};
+
+static svn_error_t *
+harvest_status_callback(void *status_baton,
+ const char *local_abspath,
+ const svn_wc_status3_t *status,
+ apr_pool_t *scratch_pool);
+
static svn_error_t *
harvest_committables(const char *local_abspath,
svn_client__committables_t *committables,
apr_hash_t *lock_tokens,
- const char *repos_root_url,
- const char *commit_relpath,
- svn_boolean_t copy_mode_root,
+ const char *copy_mode_relpath,
svn_depth_t depth,
svn_boolean_t just_locked,
apr_hash_t *changelists,
- svn_boolean_t skip_files,
- svn_boolean_t skip_dirs,
- svn_boolean_t is_explicit_target,
apr_hash_t *danglers,
svn_client__check_url_kind_t check_url_func,
void *check_url_baton,
@@ -450,38 +400,221 @@ harvest_committables(const char *local_a
void *cancel_baton,
svn_wc_notify_func2_t notify_func,
void *notify_baton,
- svn_client_ctx_t *ctx,
+ svn_wc_context_t *wc_ctx,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- svn_wc_context_t *wc_ctx = ctx->wc_ctx;
- svn_boolean_t text_mod = FALSE;
- svn_boolean_t prop_mod = FALSE;
+ struct harvest_baton baton;
+
+ baton.root_abspath = local_abspath;
+ baton.committables = committables;
+ baton.lock_tokens = lock_tokens;
+ baton.commit_relpath = copy_mode_relpath;
+ baton.depth = depth;
+ baton.just_locked = just_locked;
+ baton.changelists = changelists;
+ baton.danglers = danglers;
+ baton.check_url_func = check_url_func;
+ baton.check_url_baton = check_url_baton;
+ baton.notify_func = notify_func;
+ baton.notify_baton = notify_baton;
+ baton.wc_ctx = wc_ctx;
+ baton.result_pool = result_pool;
+
+ baton.skip_below_abspath = NULL;
+
+ SVN_ERR(svn_wc_walk_status(wc_ctx,
+ local_abspath,
+ depth,
+ (copy_mode_relpath != NULL) /* get_all */,
+ FALSE /* no_ignore */,
+ FALSE /* ignore_text_mods */,
+ NULL /* ignore_patterns */,
+ harvest_status_callback,
+ &baton,
+ cancel_func, cancel_baton,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+harvest_not_present_for_copy(svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ svn_client__committables_t *committables,
+ const char *repos_root_url,
+ const char *commit_relpath,
+ svn_client__check_url_kind_t check_url_func,
+ void *check_url_baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const apr_array_header_t *children;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+ int i;
+
+ /* A function to retrieve not present children would be nice to have */
+ SVN_ERR(svn_wc__node_get_children_of_working_node(
+ &children, wc_ctx, local_abspath, TRUE,
+ scratch_pool, iterpool));
+
+ for (i = 0; i < children->nelts; i++)
+ {
+ const char *this_abspath = APR_ARRAY_IDX(children, i, const char *);
+ const char *name = svn_dirent_basename(this_abspath, NULL);
+ const char *this_commit_relpath;
+ svn_boolean_t not_present;
+ svn_node_kind_t kind;
+
+ svn_pool_clear(iterpool);
+
+ SVN_ERR(svn_wc__node_is_status_not_present(¬_present, wc_ctx,
+ this_abspath, scratch_pool));
+
+ if (!not_present)
+ continue;
+
+ if (commit_relpath == NULL)
+ this_commit_relpath = NULL;
+ else
+ this_commit_relpath = svn_relpath_join(commit_relpath, name,
+ iterpool);
+
+ /* We should check if we should really add a delete operation */
+ if (check_url_func)
+ {
+ svn_revnum_t parent_rev;
+ const char *parent_repos_relpath;
+ const char *parent_repos_root_url;
+ const char *node_url;
+
+ /* Determine from what parent we would be the deleted child */
+ SVN_ERR(svn_wc__node_get_origin(
+ NULL, &parent_rev, &parent_repos_relpath,
+ &parent_repos_root_url, NULL, NULL,
+ wc_ctx,
+ svn_dirent_dirname(this_abspath,
+ scratch_pool),
+ FALSE, scratch_pool, scratch_pool));
+
+ node_url = svn_path_url_add_component2(
+ svn_path_url_add_component2(parent_repos_root_url,
+ parent_repos_relpath,
+ scratch_pool),
+ svn_dirent_basename(this_abspath, NULL),
+ iterpool);
+
+ SVN_ERR(check_url_func(check_url_baton, &kind,
+ node_url, parent_rev, iterpool));
+
+ if (kind == svn_node_none)
+ continue; /* This node can't be deleted */
+ }
+ else
+ SVN_ERR(svn_wc_read_kind(&kind, wc_ctx, this_abspath, TRUE,
+ scratch_pool));
+
+ SVN_ERR(add_committable(committables, this_abspath, kind,
+ repos_root_url,
+ this_commit_relpath,
+ SVN_INVALID_REVNUM,
+ NULL /* copyfrom_relpath */,
+ SVN_INVALID_REVNUM /* copyfrom_rev */,
+ SVN_CLIENT_COMMIT_ITEM_DELETE,
+ result_pool, scratch_pool));
+ }
+
+ svn_pool_destroy(iterpool);
+ return SVN_NO_ERROR;
+}
+
+/* Implements svn_wc_status_func4_t */
+static svn_error_t *
+harvest_status_callback(void *status_baton,
+ const char *local_abspath,
+ const svn_wc_status3_t *status,
+ apr_pool_t *scratch_pool)
+{
apr_byte_t state_flags = 0;
- svn_node_kind_t working_kind;
- svn_node_kind_t db_kind;
- const char *node_relpath;
- const char *node_lock_token;
svn_revnum_t node_rev;
const char *cf_relpath = NULL;
svn_revnum_t cf_rev = SVN_INVALID_REVNUM;
svn_boolean_t matches_changelists;
- svn_boolean_t is_special;
svn_boolean_t is_added;
svn_boolean_t is_deleted;
svn_boolean_t is_replaced;
- svn_boolean_t is_not_present;
- svn_boolean_t is_excluded;
svn_boolean_t is_op_root;
- svn_boolean_t is_symlink;
- svn_boolean_t conflicted;
- const char *node_changelist;
svn_boolean_t is_update_root;
svn_revnum_t original_rev;
const char *original_relpath;
- svn_boolean_t copy_mode = (commit_relpath != NULL);
+ svn_boolean_t copy_mode;
+
+ struct harvest_baton *baton = status_baton;
+ svn_boolean_t is_harvest_root =
+ (strcmp(baton->root_abspath, local_abspath) == 0);
+ svn_client__committables_t *committables = baton->committables;
+ apr_hash_t *lock_tokens = baton->lock_tokens;
+ const char *repos_root_url = status->repos_root_url;
+ const char *commit_relpath = NULL;
+ svn_boolean_t copy_mode_root = (baton->commit_relpath && is_harvest_root);
+ svn_boolean_t just_locked = baton->just_locked;
+ apr_hash_t *changelists = baton->changelists;
+ apr_hash_t *danglers = baton->danglers;
+ svn_wc_notify_func2_t notify_func = baton->notify_func;
+ void *notify_baton = baton->notify_baton;
+ svn_wc_context_t *wc_ctx = baton->wc_ctx;
+ apr_pool_t *result_pool = baton->result_pool;
+
+ if (baton->commit_relpath)
+ commit_relpath = svn_relpath_join(
+ baton->commit_relpath,
+ svn_dirent_skip_ancestor(baton->root_abspath,
+ local_abspath),
+ scratch_pool);
+
+ copy_mode = (commit_relpath != NULL);
+
+ if (baton->skip_below_abspath
+ && svn_dirent_is_ancestor(baton->skip_below_abspath, local_abspath))
+ {
+ return SVN_NO_ERROR;
+ }
+ else
+ baton->skip_below_abspath = NULL; /* We have left the skip tree */
- SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+ /* Return early for nodes that don't have a committable status */
+ switch (status->node_status)
+ {
+ case svn_wc_status_unversioned:
+ case svn_wc_status_ignored:
+ case svn_wc_status_external:
+ case svn_wc_status_none:
+ /* Unversioned nodes aren't committable, but are reported by the status
+ walker.
+ But if the unversioned node is the root of the walk, we have a user
+ error */
+ if (is_harvest_root)
+ return svn_error_createf(
+ SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("'%s' is not under version control"),
+ svn_dirent_local_style(local_abspath, scratch_pool));
+ return SVN_NO_ERROR;
+ case svn_wc_status_normal:
+ /* Status normal nodes aren't modified, so we don't have to commit them
+ when we perform a normal commit. But if a node is conflicted we want
+ to stop the commit and if we are collecting lock tokens we want to
+ look further anyway.
+
+ When in copy mode we need to compare the revision of the node against
+ the parent node to copy mixed-revision base nodes properly */
+ if (!copy_mode && !status->conflicted
+ && !(just_locked && status->lock))
+ return SVN_NO_ERROR;
+ break;
+ default:
+ /* Fall through */
+ break;
+ }
/* Early out if the item is already marked as committable. */
if (look_up_committable(committables, local_abspath, scratch_pool))
@@ -492,74 +625,71 @@ harvest_committables(const char *local_a
SVN_ERR_ASSERT((copy_mode_root && copy_mode) || ! copy_mode_root);
SVN_ERR_ASSERT((just_locked && lock_tokens) || !just_locked);
- if (cancel_func)
- SVN_ERR(cancel_func(cancel_baton));
-
- /* Return error on unknown path kinds. We check both the entry and
- the node itself, since a path might have changed kind since its
- entry was written. */
- SVN_ERR(svn_wc__node_get_commit_status(&db_kind, &is_added, &is_deleted,
- &is_replaced,
- &is_not_present, &is_excluded,
- &is_op_root, &is_symlink,
- &node_rev, &node_relpath,
- &original_rev, &original_relpath,
- &conflicted,
- &node_changelist,
- &prop_mod, &is_update_root,
- &node_lock_token,
- wc_ctx, local_abspath,
- scratch_pool, scratch_pool));
-
- if ((skip_files && db_kind == svn_node_file) || is_excluded)
- return SVN_NO_ERROR;
-
- if (!node_relpath && commit_relpath)
- node_relpath = commit_relpath;
-
- SVN_ERR(svn_io_check_special_path(local_abspath, &working_kind, &is_special,
- scratch_pool));
-
- /* ### In 1.6 an obstructed dir would fail when locking before we
- got here. Locking now doesn't fail so perhaps we should do
- some sort of checking here. */
-
- if ((working_kind != svn_node_file)
- && (working_kind != svn_node_dir)
- && (working_kind != svn_node_none))
- {
- return svn_error_createf
- (SVN_ERR_NODE_UNKNOWN_KIND, NULL,
- _("Unknown entry kind for '%s'"),
- svn_dirent_local_style(local_abspath, scratch_pool));
- }
-
/* Save the result for reuse. */
matches_changelists = ((changelists == NULL)
- || (node_changelist != NULL
- && apr_hash_get(changelists, node_changelist,
+ || (status->changelist != NULL
+ && apr_hash_get(changelists, status->changelist,
APR_HASH_KEY_STRING) != NULL));
/* Early exit. */
- if (working_kind != svn_node_dir && working_kind != svn_node_none
- && ! matches_changelists)
+ if (status->kind != svn_node_dir && ! matches_changelists)
{
return SVN_NO_ERROR;
}
- /* Verify that the node's type has not changed before attempting to
- commit. */
- if ((((!is_symlink) && (is_special))
-#ifdef HAVE_SYMLINK
- || (is_symlink && (! is_special))
-#endif /* HAVE_SYMLINK */
- ) && (working_kind != svn_node_none))
- {
- return svn_error_createf
- (SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
- _("Entry '%s' has unexpectedly changed special status"),
- svn_dirent_local_style(local_abspath, scratch_pool));
+ /* If NODE is in our changelist, then examine it for conflicts. We
+ need to bail out if any conflicts exist.
+ The status walker checked for conflict marker removal. */
+ if (status->conflicted && matches_changelists)
+ {
+ if (notify_func != NULL)
+ {
+ notify_func(notify_baton,
+ svn_wc_create_notify(local_abspath,
+ svn_wc_notify_failed_conflict,
+ scratch_pool),
+ scratch_pool);
+ }
+
+ return svn_error_createf(
+ SVN_ERR_WC_FOUND_CONFLICT, NULL,
+ _("Aborting commit: '%s' remains in conflict"),
+ svn_dirent_local_style(local_abspath, scratch_pool));
}
+ else if (status->node_status == svn_wc_status_obstructed)
+ {
+ /* A node's type has changed before attempting to commit.
+ This also catches symlink vs non symlink changes */
+
+ if (notify_func != NULL)
+ {
+ notify_func(notify_baton,
+ svn_wc_create_notify(local_abspath,
+ svn_wc_notify_failed_obstruction,
+ scratch_pool),
+ scratch_pool);
+ }
+
+ return svn_error_createf(
+ SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
+ _("Node '%s' has unexpectedly changed kind"),
+ svn_dirent_local_style(local_abspath, scratch_pool));
+ }
+
+ if (status->conflicted && status->kind == svn_node_unknown)
+ return SVN_NO_ERROR; /* Ignore delete-delete conflict */
+
+ /* Return error on unknown path kinds. We check both the entry and
+ the node itself, since a path might have changed kind since its
+ entry was written. */
+ SVN_ERR(svn_wc__node_get_commit_status(&is_added, &is_deleted,
+ &is_replaced,
+ &is_op_root,
+ &node_rev,
+ &original_rev, &original_relpath,
+ &is_update_root,
+ wc_ctx, local_abspath,
+ scratch_pool, scratch_pool));
/* Handle file externals.
* (IS_UPDATE_ROOT is more generally defined, but at the moment this
@@ -568,54 +698,42 @@ harvest_committables(const char *local_a
* Don't copy files that svn:externals brought into the WC. So in copy_mode,
* even explicit targets are skipped.
*
- * Exclude file externals from recursion. Hande file externals only when
- * passed as explicit target. Note that svn_client_commit6() passes all
- * committable externals in as explicit targets iff they count.
- *
- * Also note that dir externals will never be reached recursively by this
- * function, since svn_wc__node_get_children_of_working_node() (used below
- * to recurse) does not return switched subdirs. */
+ * Hande file externals only when passed as explicit target. Note that
+ * svn_client_commit6() passes all committable externals in as explicit
+ * targets iff they count.
+ */
if (is_update_root
- && db_kind == svn_node_file
- && (copy_mode
- || ! is_explicit_target))
+ && status->kind == svn_node_file
+ && (copy_mode || ! is_harvest_root))
{
return SVN_NO_ERROR;
}
- /* If NODE is in our changelist, then examine it for conflicts. We
- need to bail out if any conflicts exist. */
- if (conflicted && matches_changelists)
+ if (status->node_status == svn_wc_status_missing && matches_changelists)
{
- svn_boolean_t tc, pc, treec;
-
- SVN_ERR(svn_wc_conflicted_p3(&tc, &pc, &treec, wc_ctx,
- local_abspath, scratch_pool));
- if (tc || pc || treec)
+ /* Added files and directories must exist. See issue #3198. */
+ if (is_added && is_op_root)
{
if (notify_func != NULL)
{
notify_func(notify_baton,
svn_wc_create_notify(local_abspath,
- svn_wc_notify_failed_conflict,
+ svn_wc_notify_failed_missing,
scratch_pool),
scratch_pool);
}
-
return svn_error_createf(
- SVN_ERR_WC_FOUND_CONFLICT, NULL,
- _("Aborting commit: '%s' remains in conflict"),
- svn_dirent_local_style(local_abspath, scratch_pool));
+ SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+ _("'%s' is scheduled for addition, but is missing"),
+ svn_dirent_local_style(local_abspath, scratch_pool));
}
+
+ return SVN_NO_ERROR;
}
if (is_deleted && !is_op_root /* && !is_added */)
return SVN_NO_ERROR; /* Not an operational delete and not an add. */
- if (node_relpath == NULL)
- SVN_ERR(svn_wc__node_get_repos_relpath(&node_relpath,
- wc_ctx, local_abspath,
- scratch_pool, scratch_pool));
/* Check for the deletion case.
* We delete explicitly deleted nodes (duh!)
* We delete not-present children of copies
@@ -624,36 +742,6 @@ harvest_committables(const char *local_a
if (is_deleted || is_replaced)
state_flags |= SVN_CLIENT_COMMIT_ITEM_DELETE;
- else if (is_not_present)
- {
- if (! copy_mode)
- return SVN_NO_ERROR;
-
- /* We should check if we should really add a delete operation */
- if (check_url_func)
- {
- svn_client__pathrev_t *origin;
- const char *repos_url;
- svn_node_kind_t kind;
-
- /* Determine from what parent we would be the deleted child */
- SVN_ERR(svn_client__wc_node_get_origin(
- &origin, svn_dirent_dirname(local_abspath, scratch_pool),
- ctx, scratch_pool, scratch_pool));
-
- repos_url = svn_path_url_add_component2(
- origin->url, svn_dirent_basename(local_abspath, NULL),
- scratch_pool);
-
- SVN_ERR(check_url_func(check_url_baton, &kind, repos_url, origin->rev,
- scratch_pool));
-
- if (kind == svn_node_none)
- return SVN_NO_ERROR; /* This node can't be deleted */
- }
-
- state_flags |= SVN_CLIENT_COMMIT_ITEM_DELETE;
- }
/* Check for adds and copies */
if (is_added && is_op_root)
@@ -670,95 +758,70 @@ harvest_committables(const char *local_a
}
}
- /* Further additions occur in copy mode. */
- if (copy_mode
- && (!is_added || copy_mode_root)
- && !(state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))
+ /* Further copies may occur in copy mode. */
+ else if (copy_mode
+ && !(state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))
{
svn_revnum_t dir_rev;
- if (!copy_mode_root)
+ if (!copy_mode_root && !status->switched)
SVN_ERR(svn_wc__node_get_base(&dir_rev, NULL, NULL, NULL, wc_ctx,
svn_dirent_dirname(local_abspath,
scratch_pool),
scratch_pool, scratch_pool));
- if (copy_mode_root || node_rev != dir_rev)
+ if (copy_mode_root || status->switched || node_rev != dir_rev)
{
- state_flags |= SVN_CLIENT_COMMIT_ITEM_ADD;
-
- SVN_ERR(svn_wc__node_get_origin(NULL, &cf_rev,
- &cf_relpath, NULL,
- NULL, NULL,
- wc_ctx, local_abspath, FALSE,
- scratch_pool, scratch_pool));
+ state_flags |= (SVN_CLIENT_COMMIT_ITEM_ADD
+ | SVN_CLIENT_COMMIT_ITEM_IS_COPY);
- if (cf_relpath)
- state_flags |= SVN_CLIENT_COMMIT_ITEM_IS_COPY;
+ if (status->copied)
+ {
+ /* Copy from original location */
+ cf_rev = original_rev;
+ cf_relpath = original_relpath;
+ }
+ else
+ {
+ /* Copy BASE location, to represent a mixed-rev or switch copy */
+ cf_rev = status->revision;
+ cf_relpath = status->repos_relpath;
+ }
}
}
- /* If an add is scheduled to occur, dig around for some more
- information about it. */
- if (state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)
+ if (!(state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
+ || (state_flags & SVN_CLIENT_COMMIT_ITEM_ADD))
{
- /* First of all, the working file or directory must exist.
- See issue #3198. */
- if (working_kind == svn_node_none)
+ svn_boolean_t text_mod = FALSE;
+ svn_boolean_t prop_mod = FALSE;
+
+ if (status->kind == svn_node_file)
{
- if (notify_func != NULL)
+ /* Check for text modifications on files */
+ if ((state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)
+ && ! (state_flags & SVN_CLIENT_COMMIT_ITEM_IS_COPY))
{
- notify_func(notify_baton,
- svn_wc_create_notify(local_abspath,
- svn_wc_notify_failed_missing,
- scratch_pool),
- scratch_pool);
+ text_mod = TRUE; /* Local added files are always modified */
}
- return svn_error_createf(
- SVN_ERR_WC_PATH_NOT_FOUND, NULL,
- _("'%s' is scheduled for addition, but is missing"),
- svn_dirent_local_style(local_abspath, scratch_pool));
- }
-
- /* Regular adds of files have text mods, but for copies we have
- to test for textual mods. Directories simply don't have text! */
- if (db_kind == svn_node_file)
- {
- /* Check for text mods. */
- if (state_flags & SVN_CLIENT_COMMIT_ITEM_IS_COPY)
- SVN_ERR(svn_wc_text_modified_p2(&text_mod, wc_ctx, local_abspath,
- FALSE, scratch_pool));
else
- text_mod = TRUE;
+ text_mod = (status->text_status != svn_wc_status_normal);
}
- }
- /* Else, if we aren't deleting this item, we'll have to look for
- local text or property mods to determine if the path might be
- committable. */
- else if (! (state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))
- {
- /* Check for text mods on files. If EOL_PROP_CHANGED is TRUE,
- then we need to force a translated byte-for-byte comparison
- against the text-base so that a timestamp comparison won't
- bail out early. Depending on how the svn:eol-style prop was
- changed, we might have to send new text to the server to
- match the new newline style. */
- if (db_kind == svn_node_file)
- SVN_ERR(svn_wc_text_modified_p2(&text_mod, wc_ctx, local_abspath,
- FALSE, scratch_pool));
- }
-
- /* Set text/prop modification flags accordingly. */
- if (text_mod)
- state_flags |= SVN_CLIENT_COMMIT_ITEM_TEXT_MODS;
- if (prop_mod)
- state_flags |= SVN_CLIENT_COMMIT_ITEM_PROP_MODS;
+ prop_mod = (status->prop_status != svn_wc_status_normal
+ && status->prop_status != svn_wc_status_none);
+
+ /* Set text/prop modification flags accordingly. */
+ if (text_mod)
+ state_flags |= SVN_CLIENT_COMMIT_ITEM_TEXT_MODS;
+ if (prop_mod)
+ state_flags |= SVN_CLIENT_COMMIT_ITEM_PROP_MODS;
+ }
/* If the entry has a lock token and it is already a commit candidate,
or the caller wants unmodified locked items to be treated as
such, note this fact. */
- if (node_lock_token && lock_tokens && (state_flags || just_locked))
+ if (status->lock && lock_tokens && (state_flags || just_locked))
{
state_flags |= SVN_CLIENT_COMMIT_ITEM_LOCK_TOKEN;
}
@@ -769,11 +832,12 @@ harvest_committables(const char *local_a
if (matches_changelists)
{
/* Finally, add the committable item. */
- SVN_ERR(add_committable(committables, local_abspath, db_kind,
+ SVN_ERR(add_committable(committables, local_abspath,
+ status->kind,
repos_root_url,
copy_mode
? commit_relpath
- : node_relpath,
+ : status->repos_relpath,
copy_mode
? SVN_INVALID_REVNUM
: node_rev,
@@ -784,11 +848,11 @@ harvest_committables(const char *local_a
if (state_flags & SVN_CLIENT_COMMIT_ITEM_LOCK_TOKEN)
apr_hash_set(lock_tokens,
svn_path_url_add_component2(
- repos_root_url, node_relpath,
- apr_hash_pool_get(lock_tokens)),
+ repos_root_url, status->repos_relpath,
+ result_pool),
APR_HASH_KEY_STRING,
- apr_pstrdup(apr_hash_pool_get(lock_tokens),
- node_lock_token));
+ apr_pstrdup(result_pool,
+ status->lock->token));
}
}
@@ -820,7 +884,7 @@ harvest_committables(const char *local_a
}
/* Make sure we check for dangling children on additions */
- if (state_flags && is_added && is_explicit_target && danglers)
+ if (state_flags && is_added && is_harvest_root && danglers)
{
/* If a node is added, it's parent must exist in the repository at the
time of committing */
@@ -858,63 +922,26 @@ harvest_committables(const char *local_a
}
}
- if (db_kind != svn_node_dir || depth <= svn_depth_empty)
- return SVN_NO_ERROR;
-
- SVN_ERR(bail_on_tree_conflicted_children(wc_ctx, local_abspath,
- db_kind, depth, changelists,
- notify_func, notify_baton,
- scratch_pool));
-
- /* Recursively handle each node according to depth, except when the
- node is only being deleted. */
- if ((! (state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))
- || (state_flags & SVN_CLIENT_COMMIT_ITEM_ADD))
+ if ((state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
+ && !(state_flags & SVN_CLIENT_COMMIT_ITEM_ADD))
{
- const apr_array_header_t *children;
- apr_pool_t *iterpool = svn_pool_create(scratch_pool);
- int i;
- svn_depth_t depth_below_here = depth;
-
- if (depth < svn_depth_infinity)
- depth_below_here = svn_depth_empty; /* Stop recursing */
-
- SVN_ERR(svn_wc__node_get_children_of_working_node(
- &children, wc_ctx, local_abspath, copy_mode,
- scratch_pool, iterpool));
- for (i = 0; i < children->nelts; i++)
- {
- const char *this_abspath = APR_ARRAY_IDX(children, i, const char *);
- const char *name = svn_dirent_basename(this_abspath, NULL);
- const char *this_commit_relpath;
-
- svn_pool_clear(iterpool);
-
- if (commit_relpath == NULL)
- this_commit_relpath = NULL;
- else
- this_commit_relpath = svn_relpath_join(commit_relpath, name,
- iterpool);
-
- SVN_ERR(harvest_committables(this_abspath,
- committables, lock_tokens,
- repos_root_url,
- this_commit_relpath,
- FALSE, /* COPY_MODE_ROOT */
- depth_below_here,
- just_locked,
- changelists,
- (depth < svn_depth_files),
- (depth < svn_depth_immediates),
- FALSE, /* IS_EXPLICIT_TARGET */
- danglers,
- check_url_func, check_url_baton,
- cancel_func, cancel_baton,
- notify_func, notify_baton,
- ctx, result_pool, iterpool));
- }
+ /* Skip all descendants */
+ if (status->kind == svn_node_dir)
+ baton->skip_below_abspath = apr_pstrdup(baton->result_pool,
+ local_abspath);
+ return SVN_NO_ERROR;
+ }
- svn_pool_destroy(iterpool);
+ /* Recursively handle each node according to depth, except when the
+ node is only being deleted, or is in an added tree (as added trees
+ use the normal commit handling). */
+ if (copy_mode && !is_added && !is_deleted && status->kind == svn_node_dir)
+ {
+ SVN_ERR(harvest_not_present_for_copy(wc_ctx, local_abspath, committables,
+ repos_root_url, commit_relpath,
+ baton->check_url_func,
+ baton->check_url_baton,
+ result_pool, scratch_pool));
}
return SVN_NO_ERROR;
@@ -1062,7 +1089,6 @@ svn_client__harvest_committables(svn_cli
int i;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
apr_hash_t *changelist_hash = NULL;
- svn_wc_context_t *wc_ctx = ctx->wc_ctx;
struct handle_descendants_baton hdb;
apr_hash_index_t *hi;
@@ -1107,8 +1133,6 @@ svn_client__harvest_committables(svn_cli
for (i = 0; i < targets->nelts; ++i)
{
const char *target_abspath;
- svn_node_kind_t kind;
- const char *repos_root_url;
svn_pool_clear(iterpool);
@@ -1117,34 +1141,6 @@ svn_client__harvest_committables(svn_cli
APR_ARRAY_IDX(targets, i, const char *),
iterpool);
- SVN_ERR(svn_wc_read_kind(&kind, wc_ctx, target_abspath,
- FALSE, /* show_hidden */
- iterpool));
- if (kind == svn_node_none)
- {
- /* If a target of the commit is a tree-conflicted node that
- * has no entry (e.g. locally deleted), issue a proper tree-
- * conflicts error instead of a "not under version control". */
- const svn_wc_conflict_description2_t *conflict;
- SVN_ERR(svn_wc__get_tree_conflict(&conflict, wc_ctx, target_abspath,
- iterpool, iterpool));
- if (conflict != NULL)
- return svn_error_createf(
- SVN_ERR_WC_FOUND_CONFLICT, NULL,
- _("Aborting commit: '%s' remains in conflict"),
- svn_dirent_local_style(conflict->local_abspath,
- iterpool));
- else
- return svn_error_createf(
- SVN_ERR_ILLEGAL_TARGET, NULL,
- _("'%s' is not under version control"),
- svn_dirent_local_style(target_abspath, iterpool));
- }
-
- SVN_ERR(svn_wc__node_get_repos_info(&repos_root_url, NULL, wc_ctx,
- target_abspath,
- result_pool, iterpool));
-
/* Handle our TARGET. */
/* Make sure this isn't inside a working copy subtree that is
* marked as tree-conflicted. */
@@ -1155,17 +1151,13 @@ svn_client__harvest_committables(svn_cli
SVN_ERR(harvest_committables(target_abspath,
*committables, *lock_tokens,
- repos_root_url,
- NULL /* COMMIT_RELPATH */,
- FALSE /* COPY_MODE_ROOT */,
+ NULL /* COPY_MODE_RELPATH */,
depth, just_locked, changelist_hash,
- FALSE, FALSE,
- TRUE /* IS_EXPLICIT_TARGET */,
danglers,
check_url_func, check_url_baton,
ctx->cancel_func, ctx->cancel_baton,
ctx->notify_func2, ctx->notify_baton2,
- ctx, result_pool, iterpool));
+ ctx->wc_ctx, result_pool, iterpool));
}
hdb.wc_ctx = ctx->wc_ctx;
@@ -1247,14 +1239,10 @@ harvest_copy_committables(void *baton, v
/* Handle this SRC. */
SVN_ERR(harvest_committables(pair->src_abspath_or_url,
btn->committables, NULL,
- repos_root_url,
commit_relpath,
- TRUE, /* COPY_MODE_ROOT */
svn_depth_infinity,
FALSE, /* JUST_LOCKED */
- NULL,
- FALSE, FALSE, /* skip files, dirs */
- TRUE, /* IS_EXPLICIT_TARGET (don't care) */
+ NULL /* changelists */,
NULL,
btn->check_url_func,
btn->check_url_baton,
@@ -1262,7 +1250,7 @@ harvest_copy_committables(void *baton, v
btn->ctx->cancel_baton,
btn->ctx->notify_func2,
btn->ctx->notify_baton2,
- btn->ctx, btn->result_pool, pool));
+ btn->ctx->wc_ctx, btn->result_pool, pool));
hdb.wc_ctx = btn->ctx->wc_ctx;
hdb.cancel_func = btn->ctx->cancel_func;
Modified: subversion/branches/ev2-export/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/externals.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/externals.c Mon May 14 14:07:45 2012
@@ -313,9 +313,6 @@ switch_file_external(const char *local_a
const svn_opt_revision_t *revision,
const char *def_dir_abspath,
svn_ra_session_t *ra_session,
- const char *ra_session_url,
- svn_revnum_t ra_revnum,
- const char *repos_root_url,
svn_boolean_t *timestamp_sleep,
svn_client_ctx_t *ctx,
apr_pool_t *scratch_pool)
@@ -437,8 +434,7 @@ switch_file_external(const char *local_a
void *report_baton;
const svn_delta_editor_t *switch_editor;
void *switch_baton;
- const char *switch_rev_url;
- const char *repos_uuid;
+ svn_client__pathrev_t *switch_loc;
svn_revnum_t revnum;
/* ### TODO: Provide the real definition path (now available in
### def_dir_abspath) after switching to the new externals store.
@@ -447,22 +443,20 @@ switch_file_external(const char *local_a
const char *definition_abspath = svn_dirent_dirname(local_abspath,subpool);
/* Open an RA session to 'source' URL */
- SVN_ERR(svn_client__ra_session_from_path(&ra_session, &revnum,
- &switch_rev_url,
- url, dir_abspath,
- peg_revision, revision,
- ctx, subpool));
+ SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &switch_loc,
+ url, dir_abspath,
+ peg_revision, revision,
+ ctx, subpool));
SVN_ERR(svn_ra_reparent(ra_session, url, subpool));
- SVN_ERR(svn_ra_get_uuid2(ra_session, &repos_uuid, subpool));
SVN_ERR(svn_wc__get_file_external_editor(&switch_editor, &switch_baton,
&revnum, ctx->wc_ctx,
local_abspath,
definition_abspath /* wri */,
- switch_rev_url,
- repos_root_url,
- repos_uuid,
+ switch_loc->url,
+ switch_loc->repos_root_url,
+ switch_loc->repos_uuid,
use_commit_times,
diff3_cmd, preserved_exts,
definition_abspath /* def */,
@@ -477,16 +471,17 @@ switch_file_external(const char *local_a
/* Tell RA to do an update of URL+TARGET to REVISION; if we pass an
invalid revnum, that means RA will use the latest revision. */
- SVN_ERR(svn_ra_do_switch2(ra_session, &reporter, &report_baton, revnum,
- target, svn_depth_unknown, url,
- switch_editor, switch_baton, subpool));
-
- SVN_ERR(svn_wc__crawl_file_external(ctx->wc_ctx, local_abspath,
- reporter, report_baton,
- TRUE, use_commit_times,
- ctx->cancel_func, ctx->cancel_baton,
- ctx->notify_func2, ctx->notify_baton2,
- subpool));
+ SVN_ERR(svn_ra_do_switch2(ra_session, &reporter, &report_baton,
+ switch_loc->rev,
+ target, svn_depth_unknown, url,
+ switch_editor, switch_baton, subpool));
+
+ SVN_ERR(svn_wc__crawl_file_external(ctx->wc_ctx, local_abspath,
+ reporter, report_baton,
+ TRUE, use_commit_times,
+ ctx->cancel_func, ctx->cancel_baton,
+ ctx->notify_func2, ctx->notify_baton2,
+ subpool));
if (ctx->notify_func2)
{
@@ -603,10 +598,7 @@ handle_external_item_change(const struct
apr_pool_t *scratch_pool)
{
svn_ra_session_t *ra_session;
- svn_revnum_t ra_revnum;
- const char *ra_session_url;
- const char *repos_root_url;
- const char *repos_uuid;
+ svn_client__pathrev_t *new_loc;
const char *new_url;
svn_node_kind_t ext_kind;
@@ -627,29 +619,25 @@ handle_external_item_change(const struct
/* Determine if the external is a file or directory. */
/* Get the RA connection. */
- SVN_ERR(svn_client__ra_session_from_path(&ra_session,
- &ra_revnum,
- &ra_session_url,
- new_url, NULL,
- &(new_item->peg_revision),
- &(new_item->revision), eb->ctx,
- scratch_pool));
-
- SVN_ERR(svn_ra_get_uuid2(ra_session, &repos_uuid, scratch_pool));
- SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root_url, scratch_pool));
- SVN_ERR(svn_ra_check_path(ra_session, "", ra_revnum, &ext_kind,
+ SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &new_loc,
+ new_url, NULL,
+ &(new_item->peg_revision),
+ &(new_item->revision), eb->ctx,
+ scratch_pool));
+
+ SVN_ERR(svn_ra_check_path(ra_session, "", new_loc->rev, &ext_kind,
scratch_pool));
if (svn_node_none == ext_kind)
return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
_("URL '%s' at revision %ld doesn't exist"),
- ra_session_url, ra_revnum);
+ new_loc->url, new_loc->rev);
if (svn_node_dir != ext_kind && svn_node_file != ext_kind)
return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
_("URL '%s' at revision %ld is not a file "
"or a directory"),
- ra_session_url, ra_revnum);
+ new_loc->url, new_loc->rev);
/* Not protecting against recursive externals. Detecting them in
@@ -687,7 +675,7 @@ handle_external_item_change(const struct
scratch_pool));
break;
case svn_node_file:
- if (strcmp(eb->repos_root_url, repos_root_url))
+ if (strcmp(eb->repos_root_url, new_loc->repos_root_url))
{
const char *local_repos_root_url;
const char *local_repos_uuid;
@@ -707,11 +695,11 @@ handle_external_item_change(const struct
eb->ctx->wc_ctx,
parent_dir_abspath,
scratch_pool, scratch_pool));
- ext_repos_relpath = svn_uri_skip_ancestor(repos_root_url,
+ ext_repos_relpath = svn_uri_skip_ancestor(new_loc->repos_root_url,
new_url, scratch_pool);
if (local_repos_uuid == NULL || local_repos_root_url == NULL ||
ext_repos_relpath == NULL ||
- strcmp(local_repos_uuid, repos_uuid) != 0)
+ strcmp(local_repos_uuid, new_loc->repos_uuid) != 0)
return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
_("Unsupported external: URL of file external '%s' "
"is not in repository '%s'"),
@@ -720,16 +708,12 @@ handle_external_item_change(const struct
new_url = svn_path_url_add_component2(local_repos_root_url,
ext_repos_relpath,
scratch_pool);
- SVN_ERR(svn_client__ra_session_from_path(&ra_session,
- &ra_revnum,
- &ra_session_url,
- new_url,
- NULL,
- &(new_item->peg_revision),
- &(new_item->revision),
- eb->ctx, scratch_pool));
- SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root_url,
- scratch_pool));
+ SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &new_loc,
+ new_url,
+ NULL,
+ &(new_item->peg_revision),
+ &(new_item->revision),
+ eb->ctx, scratch_pool));
}
SVN_ERR(switch_file_external(local_abspath,
@@ -738,9 +722,6 @@ handle_external_item_change(const struct
&new_item->revision,
parent_dir_abspath,
ra_session,
- ra_session_url,
- ra_revnum,
- repos_root_url,
eb->timestamp_sleep, eb->ctx,
scratch_pool));
break;
Modified: subversion/branches/ev2-export/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/merge.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/merge.c Mon May 14 14:07:45 2012
@@ -8431,18 +8431,18 @@ remove_noop_subtree_ranges(const merge_s
return SVN_NO_ERROR;
}
-/* Helper for do_merge() when the merge target is a directory.
-
- Perform a merge of changes in SOURCE to the working copy path
+/* Perform a merge of changes in SOURCE to the working copy path
TARGET_ABSPATH. Both URLs in SOURCE, and TARGET_ABSPATH all represent
directories -- for the single file case, the caller should use
do_file_merge().
- MERGE_B is the merge_cmd_baton_t created by do_merge() that describes
- the merge being performed. If MERGE_B->sources_ancestral is set, then
+ MERGE_B describes the merge being performed. As this function is for a
+ mergeinfo-aware merge, MERGE_B->sources_ancestral should be TRUE, and
SOURCE->url1@rev1 must be a historical ancestor of SOURCE->url2@rev2, or
vice-versa (see `MERGEINFO MERGE SOURCE NORMALIZATION' for more
- requirements around SOURCE in this case).
+ requirements around SOURCE).
+
+ Mergeinfo changes will be recorded unless MERGE_B->dry_run is true.
If mergeinfo is being recorded, SQUELCH_MERGEINFO_NOTIFICATIONS is FALSE,
and MERGE_B->CTX->NOTIFY_FUNC2 is not NULL, then call
@@ -8469,15 +8469,15 @@ remove_noop_subtree_ranges(const merge_s
meet one or more of the criteria described in get_mergeinfo_paths()).
*/
static svn_error_t *
-do_directory_merge(svn_mergeinfo_catalog_t result_catalog,
- const merge_source_t *source,
- const char *target_abspath,
- svn_depth_t depth,
- svn_boolean_t squelch_mergeinfo_notifications,
- svn_boolean_t abort_on_conflicts,
- notification_receiver_baton_t *notify_b,
- merge_cmd_baton_t *merge_b,
- apr_pool_t *scratch_pool)
+do_mergeinfo_aware_dir_merge(svn_mergeinfo_catalog_t result_catalog,
+ const merge_source_t *source,
+ const char *target_abspath,
+ svn_depth_t depth,
+ svn_boolean_t squelch_mergeinfo_notifications,
+ svn_boolean_t abort_on_conflicts,
+ notification_receiver_baton_t *notify_b,
+ merge_cmd_baton_t *merge_b,
+ apr_pool_t *scratch_pool)
{
svn_error_t *err = SVN_NO_ERROR;
svn_error_t *merge_conflict_err = SVN_NO_ERROR;
@@ -8496,23 +8496,6 @@ do_directory_merge(svn_mergeinfo_catalog
svn_ra_session_t *ra_session;
svn_client__merge_path_t *target_merge_path;
svn_boolean_t is_rollback = (source->loc1->rev > source->loc2->rev);
- const char *primary_url = is_rollback ? source->loc1->url : source->loc2->url;
- svn_boolean_t honor_mergeinfo = HONOR_MERGEINFO(merge_b);
-
- /* Note that this is not a single-file merge. */
- notify_b->is_single_file_merge = FALSE;
-
- /* Initialize NOTIFY_B->CHILDREN_WITH_MERGEINFO. See the comment
- 'THE CHILDREN_WITH_MERGEINFO ARRAY' at the start of this file. */
- notify_b->children_with_mergeinfo =
- apr_array_make(scratch_pool, 0, sizeof(svn_client__merge_path_t *));
-
- /* If we are not honoring mergeinfo we can skip right to the
- business of merging changes! */
- if (!honor_mergeinfo)
- return do_mergeinfo_unaware_dir_merge(source,
- target_abspath, depth,
- notify_b, merge_b, scratch_pool);
/*** If we get here, we're dealing with related sources from the
same repository as the target -- merge tracking might be
@@ -8550,7 +8533,7 @@ do_directory_merge(svn_mergeinfo_catalog
range.end = source->loc2->rev;
range.inheritable = TRUE;
- if (honor_mergeinfo && !merge_b->reintegrate_merge)
+ if (!merge_b->reintegrate_merge)
{
svn_revnum_t new_range_start, start_rev;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
@@ -8743,11 +8726,11 @@ do_directory_merge(svn_mergeinfo_catalog
/* Record mergeinfo where appropriate.*/
if (RECORD_MERGEINFO(merge_b))
{
- const char *mergeinfo_path;
+ const svn_client__pathrev_t *primary_loc
+ = is_rollback ? source->loc1 : source->loc2;
+ const char *mergeinfo_path
+ = svn_client__pathrev_fspath(primary_loc, scratch_pool);
- /* ### Leaks merge_conflict_err */
- SVN_ERR(svn_ra__get_fspath_relative_to_root(ra_session, &mergeinfo_path,
- primary_url, scratch_pool));
err = record_mergeinfo_for_dir_merge(result_catalog,
&range,
mergeinfo_path,
@@ -8785,6 +8768,44 @@ do_directory_merge(svn_mergeinfo_catalog
return svn_error_compose_create(err, merge_conflict_err);
}
+/* Helper for do_merge() when the merge target is a directory.
+
+*/
+static svn_error_t *
+do_directory_merge(svn_mergeinfo_catalog_t result_catalog,
+ const merge_source_t *source,
+ const char *target_abspath,
+ svn_depth_t depth,
+ svn_boolean_t squelch_mergeinfo_notifications,
+ svn_boolean_t abort_on_conflicts,
+ notification_receiver_baton_t *notify_b,
+ merge_cmd_baton_t *merge_b,
+ apr_pool_t *scratch_pool)
+{
+ /* Note that this is not a single-file merge. */
+ notify_b->is_single_file_merge = FALSE;
+
+ /* Initialize NOTIFY_B->CHILDREN_WITH_MERGEINFO. See the comment
+ 'THE CHILDREN_WITH_MERGEINFO ARRAY' at the start of this file. */
+ notify_b->children_with_mergeinfo =
+ apr_array_make(scratch_pool, 0, sizeof(svn_client__merge_path_t *));
+
+ /* If we are not honoring mergeinfo we can skip right to the
+ business of merging changes! */
+ if (HONOR_MERGEINFO(merge_b))
+ SVN_ERR(do_mergeinfo_aware_dir_merge(result_catalog,
+ source, target_abspath, depth,
+ squelch_mergeinfo_notifications,
+ abort_on_conflicts,
+ notify_b, merge_b, scratch_pool));
+ else
+ SVN_ERR(do_mergeinfo_unaware_dir_merge(source,
+ target_abspath, depth,
+ notify_b, merge_b, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
/** Ensure that *RA_SESSION is opened to URL, either by reusing
* *RA_SESSION if it is non-null and already opened to URL's
* repository, or by allocating a new *RA_SESSION in POOL.
@@ -9098,7 +9119,7 @@ do_merge(apr_hash_t **modified_subtrees,
to represent the changed mergeinfo.
The merge is between SOURCE->url1@rev1 (in URL1_RA_SESSION1) and
- SOURCE->url2@rev2 (in URL2_RA_SESSION2); YC_REV is their youngest
+ SOURCE->url2@rev2 (in URL2_RA_SESSION2); YCA is their youngest
common ancestor.
SAME_REPOS must be true if and only if the source URLs are in the same
repository as the target working copy. Other arguments are as in
@@ -9114,7 +9135,7 @@ merge_cousins_and_supplement_mergeinfo(c
svn_ra_session_t *URL1_ra_session,
svn_ra_session_t *URL2_ra_session,
const merge_source_t *source,
- svn_revnum_t yc_rev,
+ const svn_client__pathrev_t *yca,
svn_boolean_t same_repos,
svn_depth_t depth,
svn_boolean_t ignore_ancestry,
@@ -9139,13 +9160,13 @@ merge_cousins_and_supplement_mergeinfo(c
SVN_ERR(normalize_merge_sources_internal(
&remove_sources, source->loc1,
- svn_rangelist__initialize(source->loc1->rev, yc_rev, TRUE,
+ svn_rangelist__initialize(source->loc1->rev, yca->rev, TRUE,
scratch_pool),
URL1_ra_session, ctx, scratch_pool, subpool));
SVN_ERR(normalize_merge_sources_internal(
&add_sources, source->loc2,
- svn_rangelist__initialize(yc_rev, source->loc2->rev, TRUE,
+ svn_rangelist__initialize(yca->rev, source->loc2->rev, TRUE,
scratch_pool),
URL2_ra_session, ctx, scratch_pool, subpool));
@@ -9535,7 +9556,7 @@ merge_locked(const char *source1,
ra_session1,
ra_session2,
&source,
- yca->rev,
+ yca,
same_repos,
depth,
ignore_ancestry, force,
@@ -10790,7 +10811,7 @@ merge_reintegrate_locked(const char *sou
err = merge_cousins_and_supplement_mergeinfo(target,
target_ra_session,
source_ra_session,
- source, yc_ancestor->rev,
+ source, yc_ancestor,
TRUE /* same_repos */,
svn_depth_infinity,
FALSE /* ignore_ancestry */,
@@ -11517,7 +11538,7 @@ do_symmetric_merge_locked(const svn_clie
err = merge_cousins_and_supplement_mergeinfo(target,
ra_session, ra_session,
- &source, merge->yca->rev,
+ &source, merge->yca,
TRUE /* same_repos */,
depth, ignore_ancestry,
force, record_only,
Modified: subversion/branches/ev2-export/subversion/libsvn_client/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/mergeinfo.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/mergeinfo.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/mergeinfo.c Mon May 14 14:07:45 2012
@@ -1051,13 +1051,12 @@ get_mergeinfo(svn_mergeinfo_catalog_t *m
apr_pool_t *scratch_pool)
{
svn_ra_session_t *ra_session;
- svn_revnum_t rev;
const char *local_abspath;
- const char *url;
svn_boolean_t use_url = svn_path_is_url(path_or_url);
+ const char *peg_url;
svn_revnum_t peg_rev;
- SVN_ERR(svn_client__ra_session_from_path(&ra_session, &peg_rev, &url,
+ SVN_ERR(svn_client__ra_session_from_path(&ra_session, &peg_rev, &peg_url,
path_or_url, NULL, peg_revision,
peg_revision, ctx, scratch_pool));
@@ -1071,10 +1070,9 @@ get_mergeinfo(svn_mergeinfo_catalog_t *m
SVN_ERR(svn_client__wc_node_get_origin(&origin, local_abspath, ctx,
scratch_pool, scratch_pool));
- rev = origin ? origin->rev : SVN_INVALID_REVNUM;
if (!origin
- || strcmp(origin->url, url) != 0
- || peg_rev != rev)
+ || strcmp(origin->url, peg_url) != 0
+ || peg_rev != origin->rev)
{
use_url = TRUE; /* Don't rely on local mergeinfo */
}
@@ -1088,9 +1086,8 @@ get_mergeinfo(svn_mergeinfo_catalog_t *m
if (use_url)
{
- rev = peg_rev;
SVN_ERR(svn_client__get_repos_mergeinfo_catalog(
- mergeinfo_catalog, ra_session, url, rev, svn_mergeinfo_inherited,
+ mergeinfo_catalog, ra_session, peg_url, peg_rev, svn_mergeinfo_inherited,
FALSE, include_descendants,
result_pool, scratch_pool));
}
Modified: subversion/branches/ev2-export/subversion/libsvn_client/switch.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/switch.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/switch.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/switch.c Mon May 14 14:07:45 2012
@@ -73,7 +73,8 @@ switch_internal(svn_revnum_t *result_rev
{
const svn_ra_reporter3_t *reporter;
void *report_baton;
- const char *url, *target, *source_root, *switch_rev_url;
+ const char *anchor_url, *target;
+ svn_client__pathrev_t *switch_loc;
svn_ra_session_t *ra_session;
svn_revnum_t revnum;
svn_error_t *err = SVN_NO_ERROR;
@@ -141,8 +142,9 @@ switch_internal(svn_revnum_t *result_rev
else
target = "";
- SVN_ERR(svn_wc__node_get_url(&url, ctx->wc_ctx, anchor_abspath, pool, pool));
- if (! url)
+ SVN_ERR(svn_wc__node_get_url(&anchor_url, ctx->wc_ctx, anchor_abspath,
+ pool, pool));
+ if (! anchor_url)
return svn_error_createf(SVN_ERR_ENTRY_MISSING_URL, NULL,
_("Directory '%s' has no URL"),
svn_dirent_local_style(anchor_abspath, pool));
@@ -175,20 +177,17 @@ switch_internal(svn_revnum_t *result_rev
}
/* Open an RA session to 'source' URL */
- SVN_ERR(svn_client__ra_session_from_path(&ra_session, &revnum,
- &switch_rev_url,
- switch_url, anchor_abspath,
- peg_revision, revision,
- ctx, pool));
-
- SVN_ERR(svn_ra_get_repos_root2(ra_session, &source_root, pool));
+ SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &switch_loc,
+ switch_url, anchor_abspath,
+ peg_revision, revision,
+ ctx, pool));
/* Disallow a switch operation to change the repository root of the
target. */
- if (! svn_uri__is_ancestor(source_root, url))
+ if (! svn_uri__is_ancestor(switch_loc->repos_root_url, anchor_url))
return svn_error_createf(SVN_ERR_WC_INVALID_SWITCH, NULL,
_("'%s'\nis not the same repository as\n'%s'"),
- url, source_root);
+ anchor_url, switch_loc->repos_root_url);
/* If we're not ignoring ancestry, then error out if the switch
source and target don't have a common ancestory.
@@ -197,30 +196,29 @@ switch_internal(svn_revnum_t *result_rev
### okay? */
if (! ignore_ancestry)
{
- const char *target_url;
- svn_revnum_t target_rev;
- svn_client__pathrev_t *switch_loc, *target_loc, *yca;
-
- SVN_ERR(svn_client__pathrev_create_with_session(
- &switch_loc, ra_session, revnum, switch_rev_url, pool));
- SVN_ERR(svn_wc__node_get_url(&target_url, ctx->wc_ctx, local_abspath,
- pool, pool));
- SVN_ERR(svn_wc__node_get_base(&target_rev, NULL, NULL, NULL, ctx->wc_ctx,
- local_abspath, pool, pool));
- SVN_ERR(svn_client__pathrev_create_with_session(
- &target_loc, ra_session, target_rev, target_url, pool));
- /* ### It would be nice if this function could reuse the existing
+ svn_client__pathrev_t *target_base_loc, *yca;
+
+ SVN_ERR(svn_client__wc_node_get_base(&target_base_loc, local_abspath,
+ ctx, pool, pool));
+
+ if (!target_base_loc)
+ 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_loc, ctx, pool, pool));
+ SVN_ERR(svn_client__get_youngest_common_ancestor(
+ &yca, switch_loc, target_base_loc, ctx, pool, pool));
+ }
if (! yca)
return svn_error_createf(SVN_ERR_CLIENT_UNRELATED_RESOURCES, NULL,
_("'%s' shares no common ancestry with '%s'"),
- switch_url, local_abspath);
+ switch_url,
+ svn_dirent_dirname(local_abspath, pool));
}
- SVN_ERR(svn_ra_reparent(ra_session, url, pool));
+ SVN_ERR(svn_ra_reparent(ra_session, anchor_url, pool));
/* Fetch the switch (update) editor. If REVISION is invalid, that's
okay; the RA driver will call editor->set_target_revision() later on. */
@@ -229,11 +227,11 @@ switch_internal(svn_revnum_t *result_rev
dfb.ra_session = ra_session;
SVN_ERR(svn_ra_get_session_url(ra_session, &dfb.anchor_url, pool));
- dfb.target_revision = revnum;
+ dfb.target_revision = switch_loc->rev;
SVN_ERR(svn_wc__get_switch_editor(&switch_editor, &switch_edit_baton,
&revnum, ctx->wc_ctx, anchor_abspath,
- target, switch_rev_url, use_commit_times,
+ target, switch_loc->url, use_commit_times,
depth,
depth_is_sticky, allow_unver_obstructions,
server_supports_depth,
@@ -247,10 +245,11 @@ switch_internal(svn_revnum_t *result_rev
/* Tell RA to do an update of URL+TARGET to REVISION; if we pass an
invalid revnum, that means RA will use the latest revision. */
- SVN_ERR(svn_ra_do_switch2(ra_session, &reporter, &report_baton, revnum,
+ SVN_ERR(svn_ra_do_switch2(ra_session, &reporter, &report_baton,
+ switch_loc->rev,
target,
depth_is_sticky ? depth : svn_depth_unknown,
- switch_rev_url,
+ switch_loc->url,
switch_editor, switch_edit_baton, pool));
/* Drive the reporter structure, describing the revisions within
@@ -291,7 +290,8 @@ switch_internal(svn_revnum_t *result_rev
SVN_ERR(svn_client__handle_externals(new_externals,
new_depths,
- source_root, local_abspath,
+ switch_loc->repos_root_url,
+ local_abspath,
depth, use_sleep,
ctx, pool));
}
Modified: subversion/branches/ev2-export/subversion/libsvn_client/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/update.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/update.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/update.c Mon May 14 14:07:45 2012
@@ -191,11 +191,9 @@ update_internal(svn_revnum_t *result_rev
void *update_edit_baton;
const svn_ra_reporter3_t *reporter;
void *report_baton;
- const char *anchor_url;
const char *corrected_url;
const char *target;
- const char *repos_root_url;
- const char *repos_relpath;
+ svn_client__pathrev_t *anchor_loc;
svn_error_t *err;
svn_revnum_t revnum;
svn_boolean_t use_commit_times;
@@ -223,8 +221,8 @@ update_internal(svn_revnum_t *result_rev
target = "";
/* Check if our anchor exists in BASE. If it doesn't we can't update. */
- SVN_ERR(svn_wc__node_get_base(&revnum, &repos_relpath, &repos_root_url, NULL,
- ctx->wc_ctx, anchor_abspath, pool, pool));
+ SVN_ERR(svn_client__wc_node_get_base(&anchor_loc, anchor_abspath,
+ ctx, pool, pool));
/* It does not make sense to update conflict victims. */
err = svn_wc_conflicted_p3(&text_conflicted, &prop_conflicted,
@@ -240,7 +238,7 @@ update_internal(svn_revnum_t *result_rev
else
SVN_ERR(err);
- if (!SVN_IS_VALID_REVNUM(revnum)
+ if (! anchor_loc
|| text_conflicted || prop_conflicted || tree_conflicted)
{
if (ctx->notify_func2)
@@ -258,13 +256,6 @@ update_internal(svn_revnum_t *result_rev
}
return SVN_NO_ERROR;
}
- else if (! repos_relpath)
- return svn_error_createf(SVN_ERR_ENTRY_MISSING_URL, NULL,
- _("'%s' has no URL"),
- svn_dirent_local_style(anchor_abspath, pool));
-
- anchor_url = svn_path_url_add_component2(repos_root_url, repos_relpath,
- pool);
/* We may need to crop the tree if the depth is sticky */
if (depth_is_sticky && depth < svn_depth_infinity)
@@ -333,7 +324,7 @@ update_internal(svn_revnum_t *result_rev
/* Open an RA session for the URL */
SVN_ERR(svn_client__open_ra_session_internal(&ra_session, &corrected_url,
- anchor_url,
+ anchor_loc->url,
anchor_abspath, NULL, TRUE,
TRUE, ctx, pool));
@@ -348,13 +339,15 @@ update_internal(svn_revnum_t *result_rev
SVN_ERR(svn_ra_get_repos_root2(ra_session, &new_repos_root_url, pool));
/* svn_client_relocate2() will check the uuid */
- SVN_ERR(svn_client_relocate2(anchor_abspath, repos_root_url,
+ SVN_ERR(svn_client_relocate2(anchor_abspath, anchor_loc->url,
new_repos_root_url, ignore_externals,
ctx, pool));
/* Store updated repository root for externals */
- repos_root_url = new_repos_root_url;
- anchor_url = corrected_url;
+ anchor_loc->repos_root_url = new_repos_root_url;
+ /* ### We should update anchor_loc->repos_uuid too, although currently
+ * we don't use it. */
+ anchor_loc->url = corrected_url;
}
/* ### todo: shouldn't svn_client__get_revision_number be able
@@ -368,7 +361,7 @@ update_internal(svn_revnum_t *result_rev
dfb.ra_session = ra_session;
dfb.target_revision = revnum;
- dfb.anchor_url = anchor_url;
+ dfb.anchor_url = anchor_loc->url;
/* Fetch the update editor. If REVISION is invalid, that's okay;
the RA driver will call editor->set_target_revision later on. */
@@ -430,7 +423,7 @@ update_internal(svn_revnum_t *result_rev
SVN_ERR(svn_client__handle_externals(new_externals,
new_depths,
- repos_root_url, local_abspath,
+ anchor_loc->repos_root_url, local_abspath,
depth, use_sleep,
ctx, pool));
}